rails has_many setter应该设置条件,如果指定的话

这对我来说似乎是Rails中的一个错误,但我可能做的不多。 那么我怎样才能达到预期的行为呢?

假设我们有:

class User  "Friend", :conditions => {:awesome => true} end 

并执行代码:

 >> my_user.awesome_friends <'jim') 

之后,当我检查这个朋友对象时,我看到填充了user_id字段。 但我也希望看到“真棒”这个“真棒”列,但事实并非如此。

此外,如果我从控制台执行以下操作:

 >> my_user.awesome_friends <'jim') >> my_user.awesome_friends = [#] # Quit and restart the console >> my_user.awesome_friends = [] 

有什么想法吗? 我认为条件哈希可能是任意复杂的,使得集成到setter中是不可能的。 但在某种程度上,我们感觉默认情况下我们传递的条件是“:user_id => self.id”,并且设置已经设置,其他人不应该这样做吗?

谢谢,迈克

编辑:

我发现has_many有回调,所以我想我可能会定义这样的关系:

 has_many :awesome_friends, :class_name => "Friend", :conditions => {:awesome => true}, :before_add => Proc.new{|p,c| c.awesome = true}, :before_remove => Proc.new{|p,c| c.awesome = false} 

虽然,它开始觉得我可能只是在实现其他一些现有的设计模式。 也许我应该inheritanceAwesomeFriend <朋友? 最终我需要一些这些has_many关系,并且子类化使所有额外文件变得混乱。

编辑2:

好的,感谢所有评论的人! 我最终把上面的方法整理成了一个漂亮的小ActiveRecord扩展,’has_many_of_type’。 其效果如下:

 has_many_of_type :awesome_friends, :class_name => "Friend", :type=>:awesome 

这只是在适当的条件下转换为has_many,before_add和before_remove params(并假设存在名为friend_type的列)。

你需要使用:

my_user.awesome_friends.create(:name=>'jim')my_user.awesome_friends.build(:name=>'jim')

在文档中: has_many(:conditions)

如果使用散列,则关联的记录创建是作用域的。 has_many:posts,:conditions => {:published => true}将使用@ blog.posts.create或@ blog.posts.build创建已发布的post。

它是:class_name而不是:class ,一方面。

这不是我不认为的错误。 :conditions hash只会决定你如何查询对象。 但我不认为假设您在集合中填充的任何对象可以符合条件是合理的。

在您的简单示例中,它是有道理的,但您也可以在其中放置更复杂的逻辑。

文档似乎也很清楚:

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

:conditions

指定关联对象必须满足的条件才能包含为WHERE SQL片段,例如authorized = 1