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.