问题
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
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/5783853/is-there-any-way-to-use-arel-for-custom-associations