在两个模型之间创建动态关系

Create dynamic relationship between two models

我有一个名为 changes 的模型,我将其定义为

create_table :ticket_changes do |t|
  t.string :item
  t.belongs_to :old_state
  t.belongs_to :new_state
  t.timestamps null: false
end

其中 :itemStatusTypePriority old_statesnew_states 将是 item 字段中列出的 table 记录的 ID。

构建模型时changes.rb我通常会写一行

    belongs_to :old_state, :class_name => 'TABLENAME'
    belongs_to :new_state, :class_name => 'TABLENAME'

但问题是 table 名字总是在变。任何建议,所以我可以调用 status.name 例如 @change.old_state.name 并且它知道查看状态 table 因为该记录的项目 (@change) 是 Status?

使用polymorphic associations, 这很容易。多态关联本质上允许您存储关系的 id 及其相关内容。所以在这种情况下,你可以说 old_statenew_state 可能属于其他各种模型。

您的代码将如下所示:

# migration
create_table :ticket_changes do |t|
  t.references :old_state, polymorphic: true
  t.references :new_state, polymorphic: true
  t.string :item
  t.timestamps null: false
end
# TicketChanges class
class TicketChange < ActiveRecord::Base
  belongs_to :old_state, polymorphic: true
  belongs_to :new_state, polymorphic: true
end

#Status
class Status < ActiveRecord::Base
  has_many :ticket_changes, as: :old_state
  has_many :ticket_changes, as: :new_state
end

# Type
class Type < ActiveRecord::Base
  has_many :ticket_changes, as: :old_state
  has_many :ticket_changes, as: :new_state
end

# Priority
class Priority < ActiveRecord::Base
  has_many :ticket_changes, as: :old_state
  has_many :ticket_changes, as: :new_state
end

Rails 基本上会完全按照您的计划进行,尽管它会为您想要使用 t.item 的内容创建自己的字段。

请注意,您可能需要自定义验证以确保 old_statenew_state 是同一类型的模型。 Rails 分别存储每个多态字段的模型,使得 old_state 可以是一个 Statusnew_state 可以是一个 Type.