我所拥有的一个简化示例是
class Apple < ActiveRecord::Base
has_many :bananas, as: :bananable, dependent: destroy
has_many :bananas
end
class Orange < ActiveRecord::Base
has_many :bananas, as: :bananable, dependent: destroy
end
class Banana < ActiveRecord::Base
belongs_to :bananable, polymorphic: true
belongs_to :apple
end
所以 Banana 可能属于 Apple 或 Orange 作为 bananaable,但无论如何都将通过外键关系属于 Apple。这在水果的背景下似乎有点勉强,但实际模型非常复杂,所以我简化了一些事情。基本上,多态关联定义了 Banana 存在于内部的范围,但 Banana 是 Apple 的一部分,无论其范围如何。
我遇到的问题是当我尝试创建一个新香蕉时。例如:
@Apple.bananas.new(valid_params)
这设置了 bananas 表中的 apple_id 外键列,但没有设置多态关联列(bananable_id 和 bananable_type)。我发现设置两者的唯一方法是如上所述创建一个新香蕉,然后在保存之前手动设置多态关联列。
有更好的方法吗?
也许是这样的:
@banana = @Apple.bananas.new(valid_params)
@Apple.bananables << @banana
或橙子
@banana = @Apple.bananas.new(valid_params)
@Orange.bananables << @banana
到目前为止我想到的最好的是
@banana = @Apple.bananas.new(valid_params)
if params.has_key?(:orange_id)
@banana.bananable = @orange
else
@banana.bananable = @apple
end
@banana.save
最佳答案
您可以尝试在 Banana 模型中使用 :inverse_of 属性。我知道 Rails 文档说这没有任何效果,但它似乎确实对我以前的代码有所帮助。您可以试试,但我不做任何保证。
belongs_to :bananable, polymorphic: true, inverse_of: :bananas
根据我的笔记,这有助于 Rails 理解关联及其逆关联之间的关系,对我而言,这使其能够正确识别项目类型。
作为另一种选择,请务必检查验证是否不会破坏您的数据库更新。为了测试,我不得不使用保存!以确保抛出异常,并且我可以发现隐藏的问题在哪里打破了我的联想。
关于sql - 多态关联和外键引用可以引用同一个表。如何制作新对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32771473/