Rails Scopes On Associations

I'm working on a legacy Rails application at the moment (legacy meaning it's over 10 years old - but it's recently had a revival in development activity.)

I regularly come across, what appears to be, strange ways of doing things.
At first I put it down to it being old code and perhaps that was the only way to do it "back then" but usually, after digging, I find out that it was just a deviation from "the rails way" and I task myself to rewrite it.

A good example of one of these strange ways is that throughout the applications models there are scopes that limit the resulting set of rows for an association.

This is a over simplified example - the real code includes more scopes... lots more -

scope :with_available_stays_over_price, lambda { |price|
  joins(:stays).where(property_stays: { price: price.. })
}

property.rb

The issue with this is that if we ever wanted to find stays independently of a property we'd have to duplicate the query or add a similar scope to a stay.

scope :over_price, lambda { |price|
  .where(price: price.. )
}

stay.rb

And simply utilise it on the property scope -

scope :with_available_stays_over_price, lambda { |price|
  joins(:stays).merge(Stay.over_price(price))
}

.merge was added to ActiveRecord in Rails 3 - which predates the birth of this application by at least a year 😄
I think it's lack of use is possibly down to it being a little non-railsy feeling.
There isn't a Railsy, fluent way to add conditions to a join that also allowed specific conditions on the join (i.e. part of the ON.... clause - presently they are added to the most outer WHERE conditions.)
This would make it far easier to join the same table more than once - something that currently requires complex Arel query building...

Subscribe to Useful Stuff

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe