model Post
# ActiveRecord associations have tons of options that let
# you do just about anything like:
has_many :comments
has_many :spam_comments, :conditions => ['spamm开发者_Python百科y = ?', true]
# In Rails 3, named scopes are ultra-elegant, and let you do things like:
scope :with_comments, joins(:comments)
end
Is there any way to use AREL, or an otherwise leaner syntax, to define custom associations as elegantly as named scopes?
update
I've decided it's not a good idea to put that sort of detail into an association anyway, because associations should always/mostly define the basic relationships between models.
One of the solutions is to put spammy scope on Comments:
model Post
has_many :comments
scope :with_comments, joins(:comments)
end
model Comment
scope :spammy, where(:spammy => true)
end
This looks a bit cleaner with respect to model responsibilities. Performance-wise it's exactly the same:
p.comments.spammy.to_sql
# → SELECT "comments".* FROM "comments"
# WHERE ("comments".post_id = 2) AND ("comments"."spammy" = "t")
The added benefit: you can get spammy comments from any other associations.
Well, there may be a better way, but I know that you can use actual Arel conditions (as opposed to ActiveRecord::Relations) in associations by using Arel's to_sql
feature.
has_many :spam_comments, :class_name => 'Comment', :conditions => Comment.arel_table[:spammy].eq(true).to_sql
You'll notice that actual Arel code isn't as lean as ActiveRecord Relations.
I did find a comment in the Rails master branch that referred to passing an Arel predicate as a condition but that code doesn't seem to be in the 3.0 branch. At least not that I could find.
精彩评论