建立多态 ActiveRecord 关联的正确方法
Posted
技术标签:
【中文标题】建立多态 ActiveRecord 关联的正确方法【英文标题】:Correct way of making a polymorphic ActiveRecord association 【发布时间】:2016-11-03 17:33:11 【问题描述】:我有一个User
模型和一个Dispute
模型。争议包含涉及用户的列表,以及“原告”和“被告”。我希望能够做到这一点:
Dispute.first.users
#[<User 1>, <User 2>]
Dispute.first.accuser
#<User 1>
Dispute.first.defendant
#<User 2>
这是我的模型:
class Dispute < ApplicationRecord
has_and_belongs_to_many :users
belongs_to :accuser, polymorphic: true
belongs_to :defendant, polymorphic: true
end
class User < ApplicationRecord
has_and_belongs_to_many :disputes
has_one :user, as: :accuser
has_one :user, as: :defendant
end
迁移:
class CreateDisputes < ActiveRecord::Migration[5.0]
def change
create_table :disputes do |t|
t.references :accuser, polymorphic: true, index: true
t.references :defendant, polymorphic: true, index: true
end
end
end
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.timestamps
end
end
end
这给了我想要的行为,除了 Dispute.new.save
出错,除非我将用户分配给 dispute.accuser
和 dispute.defendant
。
看起来也有问题:用户不应该有一个争议作为原告/被告吗?不过,我似乎无法让它工作。
【问题讨论】:
【参考方案1】:我可以建议一些更简单的吗?我希望我做对了。
型号:
class Dispute < ApplicationRecord
belongs_to :accuser, class_name: 'user'
belongs_to :defendant, class_name: 'user'
def users
[accuser, defendant]
end
end
class User < ApplicationRecord
end
迁移:
class CreateDisputes < ActiveRecord::Migration[5.0]
def change
create_table :disputes do |t|
t.references :accuser, index: true, references: :user
t.references :defendant, index: true, references: :user
end
end
end
【讨论】:
嘿,这很有效,而且更有意义,谢谢。Dispute
仍然存在问题,除非原告和被告字段都存在,否则无法保存。 (“原告必须存在”和“被告必须存在”错误)。我想知道为什么会这样
belongs_to :accuser, optional: true
belongs_to :defendant, optional: true
以上是关于建立多态 ActiveRecord 关联的正确方法的主要内容,如果未能解决你的问题,请参考以下文章
“undefined方法`scan'for nil:NilClass”用于多态ActiveRecord关联:inverse_of
Rails在使用多态关联时组合和排序ActiveRecord关系
ruby 使用多态数据库模型自动创建Active Record关联:http://api.rubyonrails.org/classes/ActiveRecord/Associat