【问题标题】:What should I do to make a Polymorphic Relationships in RoR?我应该怎么做才能在 RoR 中建立多态关系?
【发布时间】:2010-07-10 15:53:41
【问题描述】:

我有一个用户表和一个角色列,用于标识他们的角色。现在,我想添加一个“学生”表,其中包含学生的学号,并且我还想添加一个“教师”,以存储教师的工资。

Student 和 Teacher 都是 User 的子类。现在,我已经在 User 表中添加了一个角色列,“T” = 教师,“S” = 学生。现在,我想在数据库中添加“学生”和“老师”。我应该怎么办?只生成脚手架或迁移?另外,有必要修改我的模型吗?还是我只需要修改控制器?

谢谢。

【问题讨论】:

    标签: ruby-on-rails polymorphism


    【解决方案1】:

    这听起来更像是 Rails 的单表继承工作。它真的很容易使用。而不是使用单独的表来存储角色。从 User 继承您的学生和教师模型。 例如:

    User < ActiveRecord::Base; ... end
    Student < User; ... end
    Teacher < User; ... end
    

    Rails 自动创建一个类型列并将类存储在那里。 User.all 将返回所有用户 Student.all 将返回类型匹配 Student 的用户,Teacher.all 将对所有教师执行相同操作。

    您可以在ActiveRecord documentationhere 阅读有关单表继承的更多信息。

    【讨论】:

    • 好吧,你不再需要角色列了。您可以通过新的迁移摆脱它。但要让 STI 工作,您不需要其他任何东西。您甚至可以将 UsersController 用于管理目的,并使用单独的 StudentsController 和 TeachersController 进行特定操作。
    • 嗯,我加了一个教师脚手架,做了db:migrate,但是我去localhost:3000/teachers/new,但是报错了,我是不是也应该修改控制器而不是只修改模型?
    • 确保您的 Teacher 模型继承自 User 而不是 ActiveRecord::Base ,就像我的示例中的那样。
    【解决方案2】:

    正如 nucleussandwich 所说,这种情况需要 Rails STI(单表继承),而不是多态关联。

    只是为了突出区别:
    1)当您有不同的模型彼此非常相似但有细微差别时,使用单表继承。 STI 将所有模型集中在同一个数据库表中,并为使用该表的所有模型提供字段(列)。还有一个“类型”字段,指示该记录属于哪个模型。
    您的案例是 STI 的完美示例。您有用户、学生和教师模型,它们共享许多公共字段和功能,您只需要为学生和教师提供一个额外的字段。

    2) 当您有一个将与不同模型关联的模型时,使用多态关联。例如,假设您有一个“地址”模型。此外,您还有一个“公司”和一个“用户”模型,两者都可以有一个地址。
    在您的地址模型中,您可以指定

    belongs_to :user
    belongs_to :company
    

    然后确定地址是否属于公司不要调用address.user,反之亦然。但是,更好的方法是通过多态关联。在您的地址模型中,您可以这样做

    belongs_to :addressable, :polymorphic => true
    

    并在您的用户和公司模型中添加

    has_one :address, :as => :addressable
    

    这允许地址模型对其关联进行多态化(字面意思是:转换为多个),并通过单个关联与多个不同的模型连接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-12-11
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 2022-06-29
      相关资源
      最近更新 更多