web-dev-qa-db-ja.com

Rails 3 / Ruby:ActiveRecord Find method IN condition Array to Parameters single quote issue

User_idの配列を取得するマイクロポストモデルでメソッドを作成しました。このメソッドでは、次の「検索」メソッドを使用して、配列内のすべてのユーザーのすべての投稿を取得します。

find(:all, :conditions => ["user_id IN (?)", args.join(',')])

ただし、ActiveRecordがこのクエリのSQLを生成すると、IDのカンマ区切りリストが一重引用符で囲まれます。これにより、クエリは、すべての番号ではなく、単一引用符内の最初の番号の投稿のみを取得します。

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN ('3,4,5')) ORDER BY microposts.created_at DESC

クエリは正しく動作するように見えるはずですが、Rubyを取得して配列を引用符なしのカンマ区切りリストに変換する方法を理解できません。簡単なものでなければなりません。そして、私はそれを欠落しているだけで、これを修正するものをGoogleで見つけることができません。見つけたすべての投稿は、同じ.join( '、')メソッドを使用して配列をコンサートします。

SELECT `microposts`.* FROM `microposts` WHERE (user_id IN (3,4,5)) ORDER BY microposts.created_at DESC

私の問題を理解するのに役立つもう1つの事実は、メソッドに渡すIDの配列が次の方法で作成されていることです。これが影響を与えるかどうかはわかりません。

ids = Array.new
ids.Push(current_user.id)
ids = ids + current_user.friends.map(&:id)
ids = ids + current_user.reverse_friends.map(&:id)

私が仕事に戻るのを助けることができる人に前もって感謝します;)

30
Schleichermann

更新された回答(2回)Rails 3+ ActiveRecord syntax

Rails 3以降

次の構文を使用できます。

Post.where(user_id: [1,2,3])

したがって:

Post.where(user_id: args)

Rails 3またはRails 4(オリジナル)

完全を期すために、Rails 3構文は次のようになります。

Post.where("user_id IN (?)", [1,2,3]).to_a

ArgsがArrayの場合:

Post.where("user_id IN (?)", args).to_a

または、argsが文字列の配列の場合:

Post.where("user_id IN (?)", args.map(&:to_i)).to_a

to_aはオプションですが、結果を配列として返します。お役に立てれば。

Rails 2

次のように、単純に配列をパラメータとして渡すことができるはずです。

find(:all, :conditions => ["user_id IN (?)", [1,2,3] ] )

したがって、argsがIDの配列である場合は、次のように呼び出すだけです。

find(:all, :conditions => ["user_id IN (?)", args ] )

タイプに問題がある場合は、次のことができます。

find(:all, :conditions => ["user_id IN (?)", args.map { |v| v.to_i } ] )

これにより、配列内の各項目が整数になることが保証されます。

72
ghayes

Rails 3 and 4では、次のように配列を引数として単に渡すこともできます:

Post.where(:user_id => [1,2,3])

そしてそれはあなたに同じ結果を与えるでしょう

Post.where("user_id IN (?)", [1,2,3])
20
sq1020