1
votes

I am trying to allow users to search through their own friends by email address. I'd like to do something like:

current_user.search('[email protected]')

and have it return an array of current users friends that have that email address.

So I have a very basic friendship relationship set up on my user model

user.rb
has_many :friendships
has_many :friends, through: :friendships, source: :friend
has_many :inverse_friendships, class_name: 'Friendship', foreign_key: 'friend_id'
has_many :inverse_friends, through: :inverse_friendships, source: :user

friendship.rb
belongs_to :friend, class_name: 'User', foreign_key: 'friend_id'
belongs_to :user

I want to set up a method on my user model that can search through their friends by email address. It's not working so well

def search(query)
  conditions = ['friends.user_id = ? AND email LIKE ? ', self.id, "%#{query}%"]
  User.includes(:friends).where(conditions)
end

I guess I'm just not sure how to format my active record query / SQL here, since I am trying to search on the relations of a self referential model. Any one have any ideas?

Thanks!

3

3 Answers

1
votes

Digital Cake is going in the right direction, but not exactly correct. A scope is a method of User, not user. What you need is:

def followers_by_email(email) 
   friends.where("email like ?", "%#{email}%")
end   

This returns an ActiveRecord::Relation to which you can chain other conditions, order, paginate, etc as in

user.followers_by_email("[email protected]").order(:first_name).limit(10)
1
votes

Good time to use active record scopes. http://guides.rubyonrails.org/active_record_querying.html#scopes

Heres a simple example

user.rb

scope :followers, friends.where(:published => true).order("created_at DESC").limit(150)

in your controller

@followers = User.followers
0
votes

I seem to have some success with:

conditions = ['contacts.user_id = ? AND users.email LIKE ? ', self.id, "%#{query}%"]
User.includes(:inverse_friends).where(conditions)

Though it's strange that it works, I'm not entirely sure why it does.