Ruby on rails 在Rails中,子类化用户模型真的很糟糕吗?

Ruby on rails 在Rails中,子类化用户模型真的很糟糕吗?,ruby-on-rails,ruby,model,subclassing,Ruby On Rails,Ruby,Model,Subclassing,我从Rails得到了很多支持,因为我已经将User子类化为许多不同的子类。在我的应用程序中,并非所有用户都是平等的。实际上有很多模型对象,并不是每个用户类型都可以访问它们 我还需要一种实现多态行为的方法。例如,根据类型的不同,许多方法的行为会有所不同。多态性不就是为了这个吗 但问题是,我总是受到来自轨道的推力。默认设置——特别是表单提交参数散列的方式——似乎与非子类模型类似。链接和参数散列只是默认值真正影响你的两种方式 在Rails中,为不同类型的用户处理复杂逻辑的“正确”方法是什么?在Java

我从Rails得到了很多支持,因为我已经将User子类化为许多不同的子类。在我的应用程序中,并非所有用户都是平等的。实际上有很多模型对象,并不是每个用户类型都可以访问它们

我还需要一种实现多态行为的方法。例如,根据类型的不同,许多方法的行为会有所不同。多态性不就是为了这个吗

但问题是,我总是受到来自轨道的推力。默认设置——特别是表单提交参数散列的方式——似乎与非子类模型类似。链接和参数散列只是默认值真正影响你的两种方式


在Rails中,为不同类型的用户处理复杂逻辑的“正确”方法是什么?在Java中,子类化模型是有效的——您不必费尽心机就能让它按您想要的方式工作。但是在Rails中,很难让子类使用REST约定,当您忘记包含
:as=>:user
时,它会惩罚您,或者当您在链接中放置子类对象时,它会惩罚您,例如
edit\u user\u path(@user)
,我想出了一个窍门。但不要假设这是预期行为:

class UserSubclass < User

  def self.model_name
    User.model_name
  end

end
class-UserSubclass

默认情况下,基本上所有模型(从ActiveModel派生)都基于具体的类名来标识自己。这是通过class方法
#model_name
(它返回一个
ActiveModel::Name
的实例,参数为
self
。重写它以返回一个特定的类将Rails放在正确的轨道上。通过这种方式,您可以将该逻辑保留在模型中,而不保留在模板中。

一般来说,Ruby不鼓励继承,而支持mixin行为和委托。Ruby和Rails可以做到这一点,但它往往会导致您提到的回退

您的特定示例听起来像是一个委托案例:拥有一个属于某个员工的用户类(反之亦然)。该员工的特定类型行为(如主管、讲师等)都在特定的员工类别中。然后,用户将如何处理特定场景委托给与其加入的员工。基本上是关于“说出你的意思”

当你说“重定向到@user”时,框架无法知道你指的是通用用户表单还是专门的员工用户表单

这会导致大量的
重定向到@user.forms(user)
,您可以自由地将其删除

def to_base_class
  becomes User
end
alias_method :to_b, :to_base_class
当您打算重定向到
user
而不是
Employee
资源时,请将
redirect\u写入@user.to\u b

基本上,像
redirect_to@user
这样优雅的语法表示模型和视图/控制器之间的耦合非常深,当您使模型和视图/控制器逻辑变得更复杂时,由于这种耦合而出现的裂缝将开始显现,需要在域分离方面做一些额外的努力,或者需要编写更多的代码蒂顿

Rails并没有因为使用OOP而惩罚您,您正在经历模型-视图-控制器关系的复杂性增加:


曾几何时,你的模型是你的视图,反之亦然,现在你有两个模型类映射到两个视图类,如果你想用一个视图来表示另一个模型,你必须说这是一个巧妙的技巧。你如何处理
为:用户接受嵌套的属性以及无法设置子类之类的事情它创建了什么?我没有必要这么做,所以不是很确定。你必须深入到源代码中,找出Rails实际上在做什么,然后根据你的需要重写。不幸的是(功能,而不是bug…显然)Rails只使用他们认为是好的应用程序设计的方式来记录事情的方式,这可能不一定符合其他人的思维方式。通常,你可以超越行为,而Ruby作为一种语言本身就是这样的。@我有一种感觉,它不希望我使用子类句号。我不KN。坦白地说,我开始认为我应该为其中的所有用户角色建立一个用户类,每个has_many/behing_to关联……然后阻止人们添加他们不应该添加的内容。这可能是Rails想要的。但这很愚蠢,因为用户会有这么多人y他们甚至不会使用/无法使用的关联。此解决方案还将让我检查用户类型,以决定如何使用各种方法,因为没有多态性。如果您正在与ActiveRecord对抗,您可能会从DataMapper中获得更多乐趣。实际上我自己也使用DM,因为我发现ActiveRecord限制太多,尤其是在这样的情况下我必须使用现有的数据库,而不是新创建的数据库。它被分成许多较小的项目,因此您必须向GEM文件中添加许多
dm-*
gem,但这很容易。
dm rails
是您想要进行rails集成的项目。此外,如果您喜欢DataMapper的外观并决定尝试一下,请记住我请注意,许多gem开发人员都认为您使用的是ActiveRecord。随着时间的推移,这会变得更好,因为Rails 3还是很新的,在Rails 3之前,这样替换ActiveRecord并不容易。许多主流gem明确支持DataMapper和ActiveRecord,但不是所有较小的gem都支持。我也同意这点我对此很感兴趣。我花了一段时间打破了总是将事物子类化的习惯,转而选择将行为混合在一起。不总是,但经常。@russo:所以在我给某人发送复选标记之前,我要明确的是,我拥有的是一个没有子类化的用户类……但我有一个子类化的委托?如果用户是管理员,它会调用在代理上使用可用的关联/方法,对于oth也是如此