web-dev-qa-db-ja.com

ActiveRecord ORクエリハッシュ表記

where ActiveRecordメソッドに引数を提供するための3つの主要な表記法があることを知っています。

  1. 純弦
  2. アレイ
  3. ハッシュ

andメソッドにwhereを指定するのは簡単です:

# Pure String notation
Person.where("name = 'Neil' AND age = 27")

# Array notation
Person.where(["name = ? AND age = ?", 'Neil', 27])

# Hash notation
Person.where({name: "Neil", age: 27})

同じorメソッドにwhereを指定すると、ハッシュ構文に困惑します。出来ますか?

# Pure String notation
Person.where("name = 'Neil' OR age = 27")

# Array notation
Person.where(["name = ? OR age = ?", 'Neil', 27])

# Hash notation DOESN'T WORK
Person.where({name: "Neil" OR age: 27})
72
Neil

"ハッシュ表記"の実装と見なすことができる5つのオプションがあります(最後の2つは、ちょっとハッシュishです):

  1. Ruby on Rails 5を使用すると、 ActiveRecord::Relation#or メソッドを使用して次のチェーンを実行できます。

    Person.where(name: 'Neil').or(Person.where(age: 27))
    
  2. where_valuesreduce を併用します。 unscoped メソッドが必要です Rails 4.1+のみ)default_scopewhere_valuesに含まれないようにするためdefault_scopewhereの両方からの述語は、or演算子で連鎖されます:

    Person.where( 
      Person.unscoped.where(name: ['Neil'], age: [27]).where_values.reduce(:or) 
    )
    
  3. これらの機能または類似の機能を実装するサードパーティのプラグインをインストールします。例:

    • Whereまたは(Ruby on Rails 5 .or上記の機能)のバックポート)

    • スキール

      Person.where{(name == 'Neil') | (age == 27)} 
      
    • RailsOr

      Person.where(name: 'Neil').or(age: 27)
      
    • ActiverecordAnyOf

      Person.where.anyof(name: 'Neil', age: 27)
      
    • SmartTuple

      Person.where(
        (SmartTuple.new(' or ') << {name: 'Neil', age: 27}).compile
      )
      
  4. Arel :を使用します

    Person.where( 
      Person.arel_table[:name].eq('Neil').or(
        Person.arel_table[:age].eq(27)
      ) 
    )
    
  5. 名前付きパラメーターを使用して準備済みステートメントを使用します。

    Person.where('name = :name or age = :age', name: 'Neil', age: 27)
    
141
potashin

Potashinが言うように、この機能を実装する別のサードパーティプラグインを使用できます。 Squeel を使用するのに長い時間がかかり、この機能や、複雑なサブクエリや結合などのより多くの機能にかなり適しています。

スクイールを使用したクエリ:

@people= Person.where{(name == 'Neil') | (age = 27)}
1
Antonio Grass