John Bachir John Bachir - 4 months ago 28
Ruby Question

Is there any way to use AREL for custom associations?

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.

Answer

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.