0

ユーザーの配列の値を持つ変数を返そうとしています。満たさなければならないいくつかの条件があります。ユーザーは にpublic_find設定されてtrueいる必要があり、current_user(現在ログインしているユーザーのセッション変数) であってはならず、まだフレンドシップの一部であってはなりません。1 番目と 2 番目の条件は完全に機能します。ただし、関連付けが既に存在するユーザーcurrent_users.friendshipsの値の配列である必要がある 3 番目の部分に問題があります。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 INと を使用すると、それが悪い習慣であり、予期しない結果が返されることを私は知っていNULLます。しかし、返された配列が空の場合に値を [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] を返します。それ以外の場合は、ユーザー ID の配列を返します (外部キーとして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))])
4

2 に答える 2

1

これには arel テーブルを使用します (これにより、コードがどのデータベースでも機能することが保証されます)。

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)

に対して生成された SQLcurrent_user = 3と、次のユーザーとの 1 つのフレンドシップid = 1:

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

current_user.friendshipsisの場合nilunless 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)
于 2012-12-12T05:40:24.150 に答える