2012-12-12 69 views
0

我试图用用户数组的值返回一个变量。有几个条件必须得到满足。用户必须有public_find设置为true,它不能是current_user(当前登录用户的会话变量),并且它不能成为友谊的一部分。第一和第二个条件完美地工作。但是,我在第三部分中遇到问题,其中current_users.friendships需要是关联已存在的用户的ID值的数组。有什么想法吗?查找条件不在数组中的所有匹配条件

@users = User.find(:all, :conditions => [' 
    public_find=true AND 
    id <> ? AND 
    id NOT IN (?)', 
    current_user.id, current_user.friendships]) 

编辑:

我已经想通了,我是从失踪名单勇气。这现在很好用。但是,如果某人还没有朋友,则current_user.friendships.pluck(:friend_id)将返回NULL。我知道这是不好的做法,并且在使用NOT INNULL时会返回意外结果。但是,如果返回的数组为空,那么如何创建一个可以将值设置为[0]或[1]这样的实际值的条件?

@users = User.find(:all, :conditions => [' 
    public_find=true AND 
    id <> ? AND 
    id NOT IN (?)', 
    current_user.id, current_user.friendships.pluck(:friend_id) || [0]]) 

再次编辑:

我得到它的工作。但是,现在我想知道这是否是最佳实践,是否有这样的说法。它基本上是做一个检查,看看current_user.friendships.pluck(:friend_id)是否为空。如果是,则返回[0]。否则返回一个用户标识的数组(外键为friend_id)。

@users = User.find(:all, :conditions => [' 
    public_find=true AND 
    id <> ? AND 
    id NOT IN (?)', 
    current_user.id, 
    (current_user.friendships.pluck(:friend_id).empty? ? [0] : current_user.friendships.pluck(:friend_id))]) 

回答

1

你可以写更好这一点了..

显示所有用户,其中public_find是真实的,也排除当前登录的用户或他们的朋友

ids = current_user.friendships.map(&:friend_id).concat([current_user.id]) 
@users = User.where(:public_find => true).where('id not in ?', ids) 
1

我会用这保证了代码可以在任何数据库上工作:

t, f = User.arel_table, current_user.friendships 
query = t[:public_find].eq(true).and(t[:id].not_eq(current_user.id)) 
query = query.and(t[:id].not_in(f.pluck(:friend_id))) unless f.empty? 
@users = User.where(query) 

Generat编辑SQL的current_user = 3和一个单一的友谊与用户与id = 1

SELECT "users".* FROM "users" 
WHERE ("users"."public_find" = 't' AND "users"."id" != 3 AND "users"."id" NOT IN (1)) 

如果current_user.friendshipsnil,则unless f.empty?子句将防止应用在所有的条件,所以不会在SQL出现:

SELECT "users".* FROM "users" 
WHERE ("users"."public_find" = 't' AND "users"."id" != 3) 

此外,请注意,因为此代码使用where而不是find,最终结果是ActiveRecord::Relation而不是一组结果。这意味着你可以进一步将条件链接到它上面,例如通过updated_at订购结果,将最后一行更改为:

@users = User.where(query).order(:created_at) 
相关问题