Sie müssen or
nicht ein Upgrade auf Rails 5, um zu verwenden. Es gibt Möglichkeiten, dies in Rails 4 zu tun. Obwohl diese sich nicht besonders gut eignen, um in verketteten Bereichen verwendet zu werden, können Sie ein ähnliches Maß an Bequemlichkeit beim Aufbau Ihrer Kriterien erreichen.
Arel Tabellen. Arel ist ActiveRecords zugrundeliegende Implementierung der relationalen Algebra. Es unterstützt or
unter anderen mächtigen Dingen.
arel_table = Model.arel_table
Model.where(
arel_table[:active].eq(true).
or(
arel_table[:verified].eq(true)
)
)
# => SELECT "models".* FROM "models" WHERE ("models"."active" = 't' OR "models"."verified" = 't')
Wie Sie sehen können, ist Kriterien Chaining durch die Tatsache erschwert die or
innerhalb where
aufgebracht werden muss. Kriterien könnten extern erstellt werden, bevor sie an where
übergeben werden, aber wiederum macht ihre hierarchische Struktur es weniger einfach.
Monkeypatching ActiveRecord, Hinzufügen or
Implementierung. Setzen Sie dieses in config/initializers/active_record.rb:
ActiveRecord::QueryMethods::WhereChain.class_eval do
def or(*scopes)
scopes_where_values = []
scopes_bind_values = []
scopes.each do |scope|
case scope
when ActiveRecord::Relation
scopes_where_values += scope.where_values
scopes_bind_values += scope.bind_values
when Hash
temp_scope = @scope.model.where(scope)
scopes_where_values += temp_scope.where_values
scopes_bind_values += temp_scope.bind_values
end
end
scopes_where_values = scopes_where_values.inject(:or)
@scope.where_values += [scopes_where_values]
@scope.bind_values += scopes_bind_values
@scope
end
end
Damit können Sie or
Abfragen wie dies zu tun:
Model.where.or(verified: true, active: true)
# => SELECT "models".* FROM "models" WHERE ("models"."verified" = $1 OR "models"."active" = $2) [["verified", "t"], ["active", "t"]]
Sie weitere Kriterien hinzufügen können, wie so :
Model.where.or(verified: true, active: true, other: false)
Die Abfrage kann in eine Klasse mich gelegt werden Thod wie folgt aus:
def self.filtered(criteria)
where.or(criteria) # This is chainable!
end
oder in ihrem Umfang, der im Grunde die gleiche ist:
scope :filtered, lambda { |criteria| where.or(criteria) }
Da criteria
nur einen Hash, können Sie es auf bequeme Weise mit so vielen Elementen aufbauen können, wie Sie möchten :
criteria = {}
criteria[:verified] = true if include_verified?
criteria[:active] = true if include_active?
...
Model.filtered(criteria).where(... more criteria ...)
Und da hast du es. Lesen Sie für weitere Informationen zu dieser SO Fragen:
ActiveRecord Arel OR condition
OR operator in WHERE clause with Arel in Rails 4.2
Schließlich, falls Sie nicht auf Lösungen von Drittanbietern entgegengesetzt sind, werfen Sie einen Blick auf die Squeel gem.
Wenn Sie nicht wollen wie 'where (" active =? ODER verifiziert =? ", True, true)', dann müssen Sie auf * Rails 5 * warten, in denen 'ActiveRecord' verwendet '.oder' Betreiber.So können Sie die Bereiche wie 'Model.active.or.verified' kombinieren – Pavan
Ich bin neugierig zu wissen, gibt es einen bestimmten Grund, nicht zu verwenden oder abzufragen? – power
Es gibt mehr als 10 Bereiche und sie werden bedingt verwendet. Also wenn ich es auf diese Weise benutze, muss ich viele Permutations-Kombinationsfälle schreiben. – Imran