我从Rails得到了很多回击,因为我将User子类化为许多不同的子类。在我的应用程序中,并非所有用户都是平等的实际上有很多模型对象,并不是每个用户类型都可以访问它们。
我还需要一种做多态行为的方法。例如,许多方法的行为会有所不同,具体取决于类型。这不是多态性的用途吗?
但事实是,我总是从Rails回来。默认值 - 特别是表单提交给参数哈希的方式 - 似乎像非子类模型一样工作。链接和参数哈希只是默认设置真正咬你的两种方式。
在Rails中为不同类型的用户处理复杂逻辑的“正确”方法是什么?在Java中,子类化模型可以工作 - 您不必通过箍来使其按照您希望的方式工作。但是在Rails中,很难让子类与REST约定一起使用,当你忘记包含:as => :user
时它会惩罚你,或者当你在链接中放入子类对象时会惩罚你,例如edit_user_path(@user)
< ; - 糟糕的主意!
另外还有一个领域也很难处理。假设我有一个Company
模型,它有很多Users
。这些用户可以是导演,教师,学员等 - 所有不同的子类。
创建帐户时,我们可能希望使用accepts_nested_attributes_for :users
。但是,如果我们使用它,我们不能指定它创建的类。血淋淋的地狱!
似乎Rails中的所有内容都是为了不让您为模型创建子类。如果你没有子类,一切都“正常”。但如果你是子类,那你就是为了地狱。
解决方案是什么?
答案 0 :(得分:3)
一般来说,Ruby中不鼓励继承,而是支持mixin行为和委托。 Ruby和Rails可以做到这一点,但它往往导致你提到的推回
您的特定示例听起来像是委托的情况:拥有属于员工的User类(反之亦然)。该员工的类型特定行为(例如,董事,讲师等)都在该特定员工类中。然后,用户将委托如何处理与其加入的员工
的特定方案答案 1 :(得分:1)
这是我弄明白的一个技巧。不要假设它是预期的行为:
class UserSubclass < User
def self.model_name
User.model_name
end
end
基本上,所有模型(派生自ActiveModel)都默认根据具体的类名来标识自己。这是通过类方法#model_name
完成的(它返回ActiveModel::Name
的实例,其中self
作为参数。重写它以返回特定的类将Rails放在正确的轨道上。这样你就可以了模型中的逻辑和模板中的逻辑。
答案 2 :(得分:1)
基本上是“说出你的意思”,
如果您指的是通用用户表单或专门的员工用户表单,那么框架无法知道您何时说redirect_to @user
。
这导致很多redirect_to @user.becomes(User)
你可以自由干嘛
def to_base_class
becomes User
end
alias_method :to_b, :to_base_class
并在您打算重定向到redirect_to @user.to_b
而不是User
资源
Employee
基本上,像redirect_to @user
这样优雅的语法表示模型和视图/控制器之间的非常深度耦合,当你制作模型和视图/控制器逻辑时,由于这种耦合会产生更复杂的裂缝要显示并且需要在域分离方面做出一些额外的努力,或者需要编写更多的代码。
Rails并没有因为使用OOP而惩罚你,你正在经历模型的复杂性增加&lt; - &gt;查看&lt; - &gt;控制器关系:
曾经你的模型是你的视图,反之亦然,现在你有两个模型类映射到两个视图类,如果你想为另一个模型使用一个视图,你将不得不说出来