🏐

【備忘録】Active Recordでorを使用する

2022/08/13に公開

Railsでor検索を利用した際にすぐに出てこなかったのでメモ。

OR条件

まずはRailsガイドから。

https://railsguides.jp/active_record_querying.html#or条件

sample_model.rb
Customer.where(last_name: 'Smith').or(Customer.where(orders_count: [1,3,5]))
sample_model.sql
SELECT * FROM customers WHERE (customers.last_name = 'Smith' OR customers.orders_count IN (1,3,5))

初見だとしっくりこないが、orを呼び出した後、2個目のリレーションシップを作成すればいい。

ANDと併用する

今回の目標は次のようなSQL文を発行する。

sample_model.sql
SELECT * FROM (テーブル名) 
	WHERE カラム1 = (条件A) AND ( カラム2 = (条件B) OR カラム3 = (条件B)))

何も考えずに書くと次のようになる。

sample_model.rb
(モデル名).where(カラム1: (条件A)
                 .where(カラム2: (条件B)
                 .or((モデル名).where(カラム3: (条件B)))

発行されるのは次のSQL文

sample_model.sql
SELECT * FROM (テーブル名) 
	WHERE (カラム1 = (条件A) AND カラム2 = (条件B) OR カラム3 = (条件B))

これでは『カラム1 = (条件A) かつ カラム2 = (条件B) 』 または カラム3 = (条件B)となってしまうので、誤りである。

これを回避するにはActiveRecordのメソッドであるmergeを使用する。

https://api.rubyonrails.org/v7.0.3/classes/ActiveRecord/SpawnMethods.html#method-i-merge

sample_model.rb
(モデル名).where(カラム1: (条件A)
                 .merge((モデル名).where(カラム2: (条件B)
                 .or((モデル名).where(カラム3: (条件B))))

これで発行したいSQL文が発行できる。

Discussion