Edited at

[Rails] or を inject でチェーンする



app/models/character.rb

class Character < ApplicationRecord

enum sex: { male: 1, female: 2 }

scope :by_name, (lambda do |*names|
names.inject(none) do |relation, name|
relation.or(where("#{table_name}.name LIKE ?", "%#{name}%"))
end
end)
end


Character.female.by_name('さ', '杏').pluck(:name)

# SELECT characters.name FROM characters
# WHERE characters.sex = 2
# AND (((characters.name LIKE '%さ%') OR ((characters.name LIKE '%杏%'))
#=> ["百江なぎさ", "美樹さやか", "佐倉杏子"]


解説

Enumerable#inject の第 1 引数の none がポイント。noneself にすると

# ALL or 条件 1 or 条件 2 or ...

Character.all.or(Character.where('条件 1')).or(Character.where('条件 2'))).or(...)

と解釈されて、その結果 OR 条件が消えてしまう。