publisher_id
10、16、または17に等しいすべての投稿を取得するには、次のようにします。
Post.where(:publisher_id => [10, 16, 17])
10、16、または17にpublisher_id
等しくないすべての投稿(つまり、これら3つ以外のすべての可能なID)を取得するにはどうすればよいですか?
publisher_id
10、16、または17に等しいすべての投稿を取得するには、次のようにします。
Post.where(:publisher_id => [10, 16, 17])
10、16、または17にpublisher_id
等しくないすべての投稿(つまり、これら3つ以外のすべての可能なID)を取得するにはどうすればよいですか?
実行するだけです:
Post.where(["publisher_id NOT IN (?)", [10, 16, 17]])
Rails 4では、以下のように実行できます
Post.where.not(:publisher_id => [10, 16, 17])
以下のようなSQLを生成します
SELECT "posts".* FROM "posts" WHERE ("posts"."publisher_id" NOT IN (10, 16, 17))
テストされていませんが、次のようになります(metawhere gemを使用):
Post.where( :id.not_eq => [10,16,17] )
Rails 3を使用してArelを散りばめた「純粋な」ActiveRecord構文を使用すると、次のようなことができます。
Post.where( Post.arel_table[:publisher_id].not_in([10, 16, 17]) )
これらの回答のいずれもすべての配列の場合、特に1つの要素しかない配列を処理しないため、このページのすべての回答は間違っています。
このページの「いわゆる」ソリューションのいずれかを使用して失敗する例を次に示します。
@ids = [1]
Post.where("publisher_id NOT IN (?)", @ids)
#ERROR
Post.where("publisher_id NOT IN (?)", [4])
#ERROR
#...etc
#ALSO
@ids = []
Post.where("publisher_id NOT IN (?)", @ids)
#ERROR
Post.where("publisher_id NOT IN (?)", [])
#ERROR
#...etc
#The problem here is that when the array only has one item, only that element is
#returned, NOT an array, like we had specified
#Part of the sql that is generated looks like:
#...WHERE (publisher_id NOT IN 166)
#It should be:
#...WHERE (publisher_id NOT IN (166))
このページで実際に正しい方向に進んでいて、この非常に重要なケースを処理している唯一の答えは、@TudorConstantinです。しかし、問題は、OPが投稿した実際の抽象的な例の質問を解決するために彼の方法論を使用する「方法」を実際に示していないことです(ハードコードされた数字を使用するだけではありません)。
これは、除外するIDの配列を指定して、ActiverecordアソシエーションにないIDを動的に検索するソリューションです。これは、n個の要素の配列(... n=1およびn=0を含む)で機能します。
@ids = [166]
@attribute = "publisher_id"
@predicate = "NOT IN"
@ids = "(" + @ids.join(",") + ")"
if @ids == "()"
#Empty array, just set @ids, @attribute, and @predicate to nil
@ids = @attribute = @predicate = nil
end
#Finally, make the query
Post.where( [@attribute, @predicate, @ids].join(" ") )
#Part of the sql that is generated looks like:
#...WHERE (publisher_id NOT IN (166))
#CORRECT!
#If we had set @ids = [] (empty array)
#Then the if statement sets everything to nil, and then
#rails removes the blank " " space in the where clause automatically and does
#the query as if all records should be returned, which
#logically makes sense!
これがとにかくあなたを助けたなら、投票してください!混乱したり、私のコメントの1つがわからない場合は、お知らせください。
私が使用したきちんとした解決策:
ids = #however you get the IDS
Post.where(["id not in (?)", [0,*ids])
Post.where(" id NOT IN ( 10, 16, 17) ")