我正在开发一个Rails 3.0.x应用程序(实际上它是Hobo 1.3.x,但这不是这个问题的实质内容)。在这些模型中,有GraphPanes,GraphLabels和LabelSet。 GraphPane可以有GraphLabels和LabelSet。 GraphLabel可以属于GraphPanes 或 LabelSets,但不能同时属于两者。因此,如果GraphLabel属于LabelSet,我希望不要将其与GraphPane相关联。
我试图在GraphPane模型中使用此代码强制执行此操作:
has_many :graph_labels, :conditions => 'label_set_id = NULL'
但是,我仍然可以将GraphLabels与非空label_set_id
与GraphPanes相关联。为什么?我怎么能阻止这个?
This question表面上很相似,但我的关系不是多态的,所以那里的名义解决方案对我没有帮助。
答案 0 :(得分:1)
:conditions
上has_many
的功能是过滤通过graph_labels
传回的结果,而不是保护对象不被添加到关联中。
如果添加一个没有label_set_id的graph_label,则会建立关联,但如果您再请求graph_pane.graph_labels
,则不会返回非条件匹配的graph_label。
has_many / belongs_to关系保存在belongs_to模型graph_label上,因此parent / has_many / graph_pane不会阻止graph_label将其想要的任何内容写入其graph_pane_id属性。这个责任的授权是正确的,虽然令人沮丧,但我同意。
现在,至于如何阻止这一点,我不确定。听起来你需要对graph_label对象进行某种验证,如果graph_label的label_set_id为nil,则不允许在graph_label上设置graph_pane_id。由于has_many / belongs_to关系保存在graph_label上,因此您应该在graph_label上编写验证。这样,graph_label将无法使用新的graph_panel_id保存,除非它满足条件。
思考?有问题吗?
参考:
has_many
替代解决方案
我重读了你的问题,我想你想要的是一个多态关联。
def GraphPane < ActiveRecord::Base
has_many :label_sets
has_many :graph_labels, as: :parent
end
def LabelSet < ActiveRecord::Base
belongs_to :graph_pane
has_many :graph_labels, as: :parent
end
def GraphLabel < ActiveRecord::Base
belongs_to :parent, polymorphic: true
end
这样,GraphLabel只能有一个父母,这就是你上面的“规范”所要求的。有没有理由不以这种方式实施这种关系?