web-dev-qa-db-ja.com

Rails 5:ActiveRecord ORクエリ

Rails 5 ActiveRecordでorクエリをどのように行いますか?また、ActiveRecordクエリでorwhereと連鎖させることは可能ですか?

102

or句とwhere句をActiveRecordクエリで連結する機能は、Rails 5関連する議論とプルリクエスト をご覧ください。

そのため、Rails 5で次のことを実行できます。

post 1または2でidを取得するには

Post.where('id = 1').or(Post.where('id = 2'))

他の例:

(A && B)|| C:

    Post.where(a).where(b).or(Post.where(c))

(A || B)&& C:

    Post.where(a).or(Post.where(b)).where(c)
208

このORクエリを使用するためにRails 5を待つ必要はありません。 Rails 4.2.3でも使用できます。バックポートがあります ここ

Gemの Eric-Guo に感謝します where-or 、このgemを使用して>= Rails 4.2.3にこのOR機能を追加できます。

12
Dipak Gupta

(K M Rakibul Islamの答えに加えて)

スコープを使用すると、コードがきれいになります(見ている目によって異なります)。

scope a,      -> { where(a) }
scope b,      -> { where(b) }

scope a_or_b, -> { a.or(b) }
4
Nicholas

(A && B) || (C && D) || (E && F)を行う必要がありました

しかし、Rails 5.1.4の現在の状態では、これはArelまたはチェーンで達成するには複雑すぎます。しかし、Railsを使用して、可能な限り多くのクエリを生成したかったのです。

だから私は小さなハックを作りました:

私のモデルでは、sql_whereというprivateメソッドを作成しました。

private
  def self.sql_where(*args)
    sql = self.unscoped.where(*args).to_sql
    match = sql.match(/WHERE\s(.*)$/)
    "(#{match[1]})"
  end

次に、スコープ内でORを保持する配列を作成しました

scope :whatever, -> {
  ors = []

  ors << sql_where(A, B)
  ors << sql_where(C, D)
  ors << sql_where(E, F)

  # Now just combine the stumps:
  where(ors.join(' OR '))
}

予想されるクエリ結果が生成されます:SELECT * FROM `models` WHERE ((A AND B) OR (C AND D) OR (E AND F))

そして今、私はこれを他のスコープと簡単に組み合わせることができます。

私のsql_whereが通常のwhere-clause引数を取ることの美しさ:sql_where(name: 'John', role: 'admin')(name = 'John' AND role = 'admin')を生成します。

4
mtrolle

Rails 5には、orを含むwhere句の機能があります。例えば。

User.where(name: "abc").or(User.where(name: "abcd"))
1
Foram Thakral