Reputation: 1695
I am trying to filter the results of an user search in my app to only show users who are NOT friends. My friends table has 3 columns; f1 (userid of person who sent request), f2 (userid of friend who received request), and confirmed (boolean of true or false). As you can see, @usersfiltered is the result of the search. Then the definition of the current user's friend is established. Then I am trying to remove the friends from the search results. This does not seem to be working but should be pretty straight forward. I've tried delete (not good) and destroy.
def index
#THIS IS THE SEARCH RESULT
@usersfiltered = User.where("first_name LIKE?", "%#{params[:first_name]}%" )
#THIS IS DEFINING ROWS ON THE FRIEND TABLE THAT BELONG TO CURRENT USER
@confirmedfriends = Friend.where(:confirmed => true)
friendsapproved = @confirmedfriends.where(:f2 => current_user.id)
friendsrequestedapproved = @confirmedfriends.where(:f1 => current_user.id)
#GOING THROUGH SEARCH RESULTS
@usersfiltered.each do |usersfiltered|
if friendsapproved.present?
friendsapproved.each do |fa|
if usersfiltered.id == fa.f1
#NEED TO REMOVE THIS FROM RESULTS HERE SOMEHOW
usersfiltered.remove
end
end
end
#SAME LOGIC
if friendsrequestedapproved.present?
friendsrequestedapproved.each do |fra|
if usersfiltered.id == fra.f2
usersfiltered.remove
end
end
end
end
end
Upvotes: 1
Views: 1304
Reputation: 29399
While I agree that there may be better ways to implement what you're doing, I think the specific problem you're facing is that in Rails 4, the where
method returns an ActiveRecord::Relation
not an Array
. While you can use each
on a Relation
, you cannot in general perform array operations.
However, you can convert a Relation
to an Array
with the to_a
method as in:
@usersfiltered = User.where("first_name LIKE?", "%#{params[:first_name]}%" ).to_a
This would then allow you to do the following within your loop:
usersfiltered.delete(fa)
Upvotes: 1
Reputation: 58244
I would flip it around the other way. Take the logic that is loop-invariant out of the loop, which gives a good first-order simplification:
approved_ids = []
approved_ids = friendsapproved.map { |fa| fa.f1 } if friendsapproved.present?
approved_ids += friendsrequestedapproved.map { |fra| fra.f2 } if friendsrequestedapproved.present?
approved_ids.uniq! # (May not be needed)
@usersfiltered.delete_if { |user| approved_ids.include? user.id }
This could probably be simplified further if friendsapproved
and friendsrequestedapproved
have been created separately strictly for the purpose of the deletions. You could generate a single friendsapproval
list consisting of both and avoid unioning id sets above.
Upvotes: 1