写入has_many:通过关联和回调

时间:2011-04-12 16:48:13

标签: ruby-on-rails ruby-on-rails-3

考虑具有所需“label”属性的“Name”模型和具有以下关联的任意Rails 3模型“Foo”:

has_many :names, :dependent => :destroy
has_many :special_names, :through => :names, :source => :label, :conditions => { 'special_names.label' => 'special' }, :dependent => :destroy

现在可以访问读取关联的“special_names”属性,但写入会失败,因为AR无法从条件推断出“label”属性需要为“特殊名称”协会的所有成员设置为“特殊”。

我尝试使用“add_before”关联回调,但是永远不会使用连接模型调用(而是使用“:source”和“Foo”)。

关于如何在模型中处理这个问题的任何想法(而不是:在控制器中使用特殊逻辑来处理这个问题 - 这就是我目前处理它的方式)?

编辑 :(关于来自Ray Baxter的答案)

表达的关系 实际上是“has_many:through”关联。我会再试一次,这次有一个(希望)更好的例子:

# Label is a shared entity which is used in many contexts
has_many :labels, :through => :user_labels

# UserLabel is the join model which qualifies the usage of a Label
has_many :user_labels, :dependent => :destroy

# special_user_labels is the topic of this question
has_many :special_user_labels, :through => :user_labels, :source => :label, :conditions => { 'user_labels.descriptor' => 'special' }, :dependent => :destroy

2 个答案:

答案 0 :(得分:2)

如果我上面的评论是正确的,并且你没有has_many :through,那么这可行:

has_many :special_names, :class_name => 'Name', :conditions => {:label => 'special'}, :dependent => :destroy

所以现在你可以做到

foo = Foo.create
foo.special_name.build

ActiveRecord将使用值为label的{​​{1}}属性正确实例化您的special_name。

答案 1 :(得分:0)

我找到了解决方案(感谢x0f @Freenode) - 需要将“特殊”关联分成两部分。 has_many :special_user_labels, :through => :user_labels, :source => :label, :conditions => { 'user_labels.descriptor' => 'special' }, :dependent => :destroy成为

1)has_many :special_labels, :class_name => 'UserLabel', :conditions => { :descriptor => 'special' }, :dependent => :destroy

2)has_many :special_user_labels, :through => :special_labels, :source => :label, :dependent => :destroy

适合阅读和阅读写作以及(范围)hbtm协会的无缝替代。