3
Help us understand the problem. What are the problem?

posted at

updated at

Organization

WHERE A and (B or C)をActiveRecordで記述する方法

Railsアプリケーション開発中に、WHERE A and (B or C)のようなSQLをActiveRecordのデータアクセスメソッドで書くときにどうすれば良いのか少しハマったのでメモとして残します。

SQL
SELECT *
FROM model
WHERE A and (B or C) ;

結論

mergeメソッドを使用する。
括弧に該当するメソッドがmergeメソッドとなる。

ActiveRecord
Model.where(A).merge(where(B).or(where(C)))

例: ポケモン

例えば、こんな感じのポケモンテーブルがあったとする

db/migrate/pokemon.rb
class Pokemons < ActiveRecord::Migration[5.2]
  def change
    create_table :pokemons do |t|
      t.string name
      t.string type
    end
  end
end

idが1~10かつ(炎タイプまたは水タイプ)のポケモンのみを取得したい場合

SQLで書くならこうなる

SQL
SELECT *
FROM pokemon
WHERE id BETWEEN 1 AND 10
AND (type = '炎' OR type = '水'); 

ActivrRecordのメソッドを使用すると・・・

ActiveRecord
@pokemons = Pokemon.where(id: 1..10).merge(where(type: '炎').or(where(type: '水')))

この部分だけ、何度も取得する必要がある場合は、pokemonモデルにscopeとして定義しても良い

pokemon.rb
scope :filter_type, -> { merge(where(type: '炎').or(where(type: '水'))) }

// 呼び出し先
@pokemons = Pokemon.filter_type

おまけ

WHERE A and (B or C or D)

Model.where(A).merge(where(B).or(where(C)).or(where(D)))

WHERE (A or B) and (C or D)

Model.merge(where(A).or(where(B))).merge(where(C)).or(where(D)))

参考

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
3
Help us understand the problem. What are the problem?