Escopos Chain Rails com OR

Uma das deficiências dos escopos no ActiveRecord é a incapacidade de encadea-los em uma cláusula “OU”. Aqui está uma maneira de fazer isso. O uso não é particularmente elegante, mas dá conta do recado.

Preocupação com o comportamento OR

module ModelHasScopeHelpers
extend
ActiveSupport::Concern

module ClassMethods

# Creates a new scope with with all where clauses joined by "OR"
# Preserves selects & orders but ignores all other query elements.
def or_scopes(*scopes)
selects
= []
orders
= []
wheres
= scopes.map do |scope|
selects
<< scope.projections
orders
<< scope.orders
if scope.arel.where_sql.present?
scope
.arel.where_sql.gsub(/AWHERE /i, "")
else
nil
end
end
scope
= where(wheres.compact.join(" OR "))
selects
.flatten.each { |s| scope = scope.select(s) }
orders
.flatten.each { |o| scope = scope.order(o) }
scope

end

end

end

Modelo

model User < ActiveRecord::Base
include
ModelHasScopeHelpers
end

Uso

users = User.or_scopes(
User.where(name: "Bob"),
User.where(name: "Bobby"),
User.where(name: "Bobbie")
)