Search code examples
rubyactiverecordscopesyntactic-sugardatabase-relations

How to magically supply Active Record scopes with arguments?


I'm not sure this is even possible, but let's see if one of you comes up with a solution. This is more or less about code quality in terms of readability and not an actual problem because I already have a solution. I have a friendship model and a user model. The friendship model is used to model friendships between two users:

class Friendship

  def self.requested(user)
    where(:user_id => user).where(:status => 'requested')
  end

  def self.pending(user)
    where(:user_id => user).where(:status => 'pending')
  end

  def self.accepted(user)
    where(:user_id => user).where(:status => 'accepted')
  end

  # ...

end

class User
   has_many :friendships

   # ...
end

Is it somehow possible to call the requested, pending or accepted scope through the user model without providing an argument?

a_user.friendships.pending # this does not work, is there a way to get it working?

a_user.friendships.pending(a_user) # works of course!

Solution

  • I think this should work if you take the argument off. Calling pending off of the user object like this should already scope friendships to the appropriate user. Define the method like this:

    def self.pending
      where(:status => 'pending')
    end
    

    And call:

    a_user.friendships.pending
    

    Check the logs for the generated query if you're not sure it's working.

    If you still want to call it by passing an argument I'd name that method Friendship.pending_for(user).