Use a scope by default on a Rails has_many relationship
Solution 1:
In Rails 4, Associations
have an optional scope
parameter that accepts a lambda that is applied to the Relation
(cf. the doc for ActiveRecord::Associations::ClassMethods)
class SolarSystem < ActiveRecord::Base
has_many :planets, -> { life_supporting }
end
class Planet < ActiveRecord::Base
scope :life_supporting, -> { where('distance_from_sun > ?', 5).order('diameter ASC') }
end
In Rails 3, the where_values
workaround can sometimes be improved by using where_values_hash
that handles better scopes where conditions are defined by multiple where
or by a hash (not the case here).
has_many :planets, conditions: Planet.life_supporting.where_values_hash
Solution 2:
In Rails 5, the following code works fine...
class Order
scope :paid, -> { where status: %w[paid refunded] }
end
class Store
has_many :paid_orders, -> { paid }, class_name: 'Order'
end
Solution 3:
i just had a deep dive into ActiveRecord and it does not look like if this can be achieved with the current implementation of has_many
. you can pass a block to :conditions
but this is limited to returning a hash of conditions, not any kind of arel stuff.
a really simple and transparent way to achieve what you want (what i think you are trying to do) is to apply the scope at runtime:
# foo.rb
def bars
super.baz
end
this is far from what you are asking for, but it might just work ;)