2

I'm doing an add friend function, in the add friend page, I want to dis play all the users except the current user and the user's friends, followed by an "add" button. But I can only display all users either without current user or the user's friends. Here's my code in user model:

scope :all_except, ->(user) { where.not(id: user) && where.not(id: user.friends)}

Here's the user controller:

@users = User.all_except(current_user)

Here's the view:

<% for user in @users %>
    <div class="user">
      <p>
        <strong><%=h user.name %></strong>
        <%= link_to "Add Friend", friendships_path(:friend_id => user), :method => :post %>
      <div class="clear"></div>
      </p>
    </div>
 <% end %>

By doing this, the user's friends won't display on the page, but current user's name still there.. Can someone help? Thanks!

I tried to change the code, if I use

scope :all_except, ->(user) { where.not(id: user) && where.not(id: user.friends)}

where.not(id: user) doesn't work, and if I use

scope :all_except, ->(user) {where.not(id: user.friends) && where.not(id: user)}

where.not(id: user.friends) doesn't work

awendt
  • 13,195
  • 5
  • 48
  • 66
jacobbb
  • 101
  • 9
  • What is the error you get ? What "doesn't work"? – MrPizzaFace Oct 19 '14 at 18:07
  • So you see current_user and others but not friends? – MrPizzaFace Oct 19 '14 at 18:14
  • There comes an error this time, ActiveRecord::StatementInvalid in User#index SQLite3::SQLException: near "SELECT": syntax error: SELECT "users".* FROM "users" WHERE (id != 3 AND id != SELECT "users"."id" FROM "users" INNER JOIN "friendships" ON "users"."id" = "friendships"."friend_id" WHERE "friendships"."user_id" = ?) – jacobbb Oct 19 '14 at 18:28
  • the first one was same result, and second one got an error too...SQLite3::SQLException: near ",": syntax error: SELECT "users".* FROM "users" WHERE (id != 1,3) – jacobbb Oct 19 '14 at 18:38
  • Syntax was a little off. I updated my answer. That is what you need. Try it and let me know. :) – MrPizzaFace Oct 19 '14 at 18:50
  • it displayed all the users...but really thanks a lot for ur help, is there any other ways? i think in the first error, the system did FROM "users" INNER JOIN "friendships" ON "users"."id" = "friendships"."friend_id" WHERE "friendships"."user_id" = ?) but it may should be FROM "users" INNER JOIN "friendships" ON "users"."id" = "friendships"."user_id" WHERE "friendships"."friend_id" = ?), is it? – jacobbb Oct 19 '14 at 18:52
  • But thats what you asked for? To display ALL users that are NOT current_user OR current_users_friends. So it should display all the users that fit that criteria. – MrPizzaFace Oct 19 '14 at 18:55
  • possible duplicate of [Rails ActiveRecord: Find All Users Except Current User](http://stackoverflow.com/questions/2672744/rails-activerecord-find-all-users-except-current-user) – Mohamad Feb 12 '15 at 16:03

4 Answers4

3

If you want your scope to have more than one condition, you cannot chain them with &&.

These are two method calls that just happen to be called in order if the first returns something truthy but only the last will determine the outcome of your scope.

Thus, your first where is completely ignored in that scope. Try swapping the two wheres and you'll see: the current user is excluded but not her friends.

It should be:

scope :all_except, ->(user) { where.not(id: (user.friends + [user]).map(&:id))}
awendt
  • 13,195
  • 5
  • 48
  • 66
0

Try using this:

scope :all_except,
  ->(user) { where.not(id: user) && where.not(id: user.friends.map(&:id))}

or

scope :all_except,
  ->(user) { where.not(id: user) && where.not(id: user.friends.select(:id))}
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497
  • it's same with before, the current user still there – jacobbb Oct 19 '14 at 16:30
  • I think @michael ment to say `->(user) { where.not(id: user) && where(id: user.friends.map(&:id))}` try that. – MrPizzaFace Oct 19 '14 at 16:43
  • @fab i tried what you said, but this time only user's friends was displayed. what i want is not user's friend and not user. – jacobbb Oct 19 '14 at 18:01
  • @jacobb I misread the question. I thought you wanted only the users friends. In that case Michael's answer is correct. Perhaps your associations are not setup properly. Update your question and show your models. – MrPizzaFace Oct 19 '14 at 18:06
0

To display ALL users that are NOT current_user OR current_users_friends, this should work for you:

scope :all_except, ->(user) { where(["id NOT IN (?)", ([user.friends.map(&:id) << user.id]) ]) }
MrPizzaFace
  • 7,807
  • 15
  • 79
  • 123
  • If it's showing all users then you are not passing in the proper ID's your error shows only two id's 1,3. This code does what you need. Your issue is somewhere else. – MrPizzaFace Oct 19 '14 at 19:04
0

Try this :

scope :all_except,->(user) {where.not(id: (user.friends.map(&:id) + user.id)}
Aaditi Jain
  • 6,969
  • 2
  • 24
  • 26