7

ID の配列 (クライアント側から受信) があるとします。

myArray = [1,5,19,27]

そして、(セカンダリ)IDがそのリストにあるすべてのアイテムを返したいと思います。

SQL では、次のようになります。

SELECT * FROM Items WHERE id IN (1,5,19,27)

私はできることを知っています:

Item.where(id: [1,5,9,27])

ただし、これが追加されるより長い where クエリは、準備されたステートメント構文を使用しますItem.where('myAttrib = ? AND myOtherAttrib <> ? AND myThirdAttrib = ?', myVal[0], myVa[1], myVal[2])

それを念頭に置いて、私が望むことは次のとおりです。

Item.where('id IN ?', myArray)

ただし、構文エラーが発生します。

ActiveRecord::StatementInvalid: PG::Error: ERROR: syntax error at or near "1" LINE 1: SELECT "items".* FROM "items" WHERE (id in 1,2,3,4)

どうすればこれを回避できますか? 式の準備済みステートメント構文で where を使用する正しい方法は何ですかIN

4

3 に答える 3

14

私は最終的に使用しました:

Item.where('id IN (?)', myArray)

于 2013-09-30T17:57:56.827 に答える
3

クエリを次のように変更する必要があります。

Item.where('id = ?', myArray)

myArray が実際に配列である場合、ActiveRecord はこれを IN 句に変換します。

于 2013-09-29T08:38:19.987 に答える
1

生の SQL を使用する際の問題は、Rails と AREL によって無料で提供される列名の自動名前空間が失われることです。

生の SQL を使用すると、クエリまたはスコープを結合およびマージするとき、または結合を行うときに問題が発生し始める可能性があります。

使用するために生のSQLを使用する必要はありませんIN:

Item.where(:id => myArray) # SELECT * FROM items WHERE id IN (...)

myArrayは、値の配列または の配列Items、または単一の値のいずれかです。

Rails は、SQL を意図したとおりに変更できるほどスマートです。実際、配列に が含まれている場合nil、SQL は になりますSELECT * FROM items WHERE (id IS NULL or id IN (...))。これは、静的で単一のユース ケースしか処理できない生の SQL を使用するよりも明らかに優れています。

Rails が必要なものを提供しない場合は、AREL に頼ることができます。例えば:

class Item
  scope :with_category, ->(categories) {
    where( arel_table[:category].in(categories) )
  }

  scope :filter, ->(a, b, c) {
    not_b = arel_table[:myOtherAttrib].not_eq(b)
    where(:myAttrib => a, :myThirdAttrib => c).where(not_b)
  }
end

Item.with_category(['small', 'large']).filter(*myVal)
于 2015-11-06T01:48:18.800 に答える