我所拥有的简化示例
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
所以香蕉可能属于苹果或橙子,但是无论如何都属于苹果通过外键关系。这在水果的背景下似乎有点被迫,但实际的模型非常复杂,所以我简化了一些事情。基本上,多态关联定义了香蕉存在的范围,但香蕉是苹果的一部分,无论其范围如何。
我遇到的问题是当我尝试制作新香蕉时。例如:
@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
答案 0 :(得分:1)
您可以尝试在Banana模型中使用:inverse_of属性。我知道Rails文档说这没有任何效果,但它确实在我之前的代码中做了一些帮助。你可以尝试,但我不保证。
belongs_to :bananable, polymorphic: true, inverse_of: :bananas
从我的笔记中,这有助于Rails理解关联与其反转之间的关系,这对我来说可以正确识别项目类型。
作为另一种选择,请务必检查验证是否违反了数据库更新。为了测试,我不得不使用保存!确保抛出异常,我可以发现隐藏的问题破坏了我的关联。
答案 1 :(得分:0)
首先要清楚地了解多态关联。 Ruby on Rails指南指出“with polymorphic associations, a model can belong to more than one other model, on a single association”
。
我确信您不需要两个关联到同一张桌子。每当您创建banana
到apple
时,bananable_id
和bananable_type
都不会被设置,因为rails会通过apple_id
找到关联,并且它不会#&# 39;打扰任何其他协会。
据我所知,您的模型不必要地复杂化。 我敢打赌,以下关联可以获得您需要的所有功能。
class Apple < ActiveRecord::Base
has_many :bananas, as: :bananable, dependent: destroy
end
class Orange < ActiveRecord::Base
has_many :bananas, as: :bananable, dependent: destroy
end
class Banana < ActiveRecord::Base
belongs_to :bananable, polymorphic: true
end
如果您有任何有效的要点说明为什么您需要两个相同型号的关联,请发表评论。