What is the equivalent of the has_many 'conditions' option in Rails 4?
Solution 1:
Needs to be the second arg:
class Customer < ActiveRecord::Base
has_many :orders, -> { where processed: true }
end
http://edgeguides.rubyonrails.org/association_basics.html#scopes-for-has-many
RESPONSE TO UPDATE:
Put the order inside the block:
has_many :friends, -> { where(friendship: {status: 'accepted'}).order('first_name DESC') }, :through => :friendships
Solution 2:
While other answers on here are technically correct, they violate encapsulation. The User model should not know that the Friendship model has a column called status
, and that it can have a specific value like accepted
.
If you decide to make a change, to take advantage of Enums in Rails 4, for example, you would have to change both User and Friendship models. This could lead to bugs that maintaining encapsulation avoids.
I would expose a scope in the Friendship model:
scope :accepted, -> { where(status: :accepted) }
I would then use this scope in the User model, hiding any implementation details from User.
has_many :friendships, -> { Friendship.accepted }
has_many :friends, through: :friendships
# Or...
has_many :friends, -> { Friendship.accepted }, through: :friendships
You can go further and rename the scope to accepted_friendships
to be clearer.
has_many :accepted_friendships, -> { Friendship.accepted }
has_many :friends, through: :accepted_friendships
Now you have successfully encapsulated implementation details in their respective models. Should anything change you only have one place to change it, reducing maintenance and increasing robustness.