2011-04-25 174 views
4
model Post 
    # ActiveRecord associations have tons of options that let 
    # you do just about anything like: 
    has_many :comments 
    has_many :spam_comments, :conditions => ['spammy = ?', true] 

    # In Rails 3, named scopes are ultra-elegant, and let you do things like: 
    scope :with_comments, joins(:comments) 
end 

有没有什么方法可以使用AREL或其他更精简的语法来将自定义关联定义为与命名作用域一样优雅?有没有办法使用AREL进行自定义关联?

更新

我已经决定了这不是一个好主意,把那种细节的为关联关系,无论如何,因为协会应始终/大都定义模型之间的基本关系。

回答

3

解决的办法之一就是把垃圾范围点评:

model Post 
    has_many :comments 

    scope :with_comments, joins(:comments) 
end 

model Comment 
    scope :spammy, where(:spammy => true) 
end 

这看起来有点清洁关于模型的责任。性能方面它是完全一样的:

p.comments.spammy.to_sql 
# → SELECT "comments".* FROM "comments" 
# WHERE ("comments".post_id = 2) AND ("comments"."spammy" = "t") 

额外的好处:你可以从任何其他协会取得垃圾评论。

+0

是的我见过这个......我认为把它称为“关联”并不好,因为它没有定义两个模型之间的关系。 – 2011-04-26 15:34:30

+0

性能明智,这是否具有与通过关联限制查询相同的效果? (初学者在这里) – noli 2011-07-15 03:25:01

2

那么,可能有更好的方法,但我知道你可以使用实际的Arel条件(而不是ActiveRecord::Relation)在关联中使用Arel的to_sql功能。

has_many :spam_comments, :class_name => 'Comment', :conditions => Comment.arel_table[:spammy].eq(true).to_sql 

您会注意到实际的Arel代码不像ActiveRecord关系那么精简。

我确实在Rails master分支中发现了a comment,它引用了将Arel谓词作为条件传递,但代码似乎不在3.0分支中。至少不是我能找到的。

相关问题