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
。