您的连接方法将导致多个数据库查询,并且不能链接,这通常是分页、范围、分组和排序所需要的。
相反,我会收集您的条件并在最后合并。看起来您的条件实际上是 OR 类型查询,而不是更容易链接的 AND 类型查询。
因此,请执行以下操作:
@queries = []
if some_condition
# Relation condition
@queries << MyModel.where(...)
end
if another_condition
# another Relation condition
@queries << MyModel.where(...)
end
if and_another_condition
# Hash equality and IN conditions
@queries << { attr1: 'foo', attr2: [1,2,3] }
end
if yet_another_condition
# string condition with argument
@queries << ['attr LIKE ? ', arg]
end
@items = MyModel.any_of(*queries).order(...).page(...).per(...)
神奇之处在于一个漂亮的自定义 AR 扩展方法any_of?
,用于使用 Arel 组合 OR 类型查询。它可以采用关系、字符串条件、哈希条件或数组来插入 where() 子句。
# put in config/initializers/ar_any_of.rb or in lib/xxxx
class ActiveRecord::Base
def self.any_of(*queries)
where(
queries.map { |query|
query = where(query) if [String, Hash].any? { |type| query.kind_of? type }
query = where(*query) if query.kind_of? Array
query.arel.constraints.reduce(:and)
}.reduce(:or)
)
end
end
它可以与以下各种条件一起使用以生成单个 SQL:
Country.any_of(
Country.where(alpha2: 'AU'),
{ alpha2: ['NZ', 'UK'] },
['alpha2 LIKE ?', 'U%']).to_sql
# => "SELECT \"countries\".* FROM \"countries\" WHERE (((\"countries\".\"alpha2\" = 'AU' OR \"countries\".\"alpha2\" IN ('NZ', 'AD')) OR (alpha2 LIKE 'U%')))"