Wenn ich ein ActiveRecord :: Base-Modell mit einem Standardbereich habe:
class Foo < ActiveRecord::Base
default_scope :conditions => ["bar = ?",bar]
end
Gibt es eine Möglichkeit, Foo.find
ohne die default_scope
Bedingungen zu nutzen? Mit anderen Worten, können Sie einen Standardbereich überschreiben?
Ich hätte gedacht , dass die Verwendung von ‚default‘ im Namen würde vorschlagen , dass es war außer Kraft gesetzt werden , sonst wäre es so etwas wie genannt wird global_scope
, nicht wahr?
ruby-on-rails
Gareth
quelle
quelle
Antworten:
Kurze Antwort: Nicht verwenden, es
default_scope
sei denn, Sie müssen wirklich. Mit benannten Bereichen sind Sie wahrscheinlich besser dran.with_exclusive_scope
Wenn dies erforderlich ist , können Sie den Standardbereich bei Bedarf überschreiben.Schauen Sie sich diese Frage für weitere Details an.
quelle
default_scope
scheint eine gute Idee zu sein, verursacht jedoch wahrscheinlich mehrere Kopfschmerzen während der Lebensdauer Ihrer App.with_exclusive_scope
wurde in Schienen 3 entferntdefault_scope
ist ein ausgezeichnetes Werkzeug und es gibt Situationen, in denen Sie einen anderen Weg gehen könnten, aber es istdefault_scope
genau das Richtige. Wenn Sie beispielsweise einProduct
Modell mit einerinactive
Flagge haben,default_scope { where inactive: false }
ist es am besten, eine zu setzen, da Sie in 99% oder Fällen kein inaktives Produkt anzeigen möchten. Dann rufen Sie einfachunscoped
die verbleibenden 1% -Fälle auf, bei denen es sich wahrscheinlich um ein Admin-Panel handelt.In Schienen 3:
quelle
def self.random; unscoped.order('rand()'); end
einfügen : unscoped entfernt ALL SQL zuvor, nicht nur das, was unter default_scope aufgeführt ist. Obwohl technisch eine korrekte Antwort, seien Sie vorsichtig mitunstopped
unscoped
wenn es einem Modell direkt folgen kann, zBFoo.unscoped.blah()
ist es ok aber nieFoo.blah().unscoped
.Wenn Sie nur die in definierte Reihenfolge ändern müssen
default_scope
, können Sie diereorder
Methode verwenden .führt die folgende SQL aus:
quelle
scope :without_default_order, -> { reorder("") }
und Sie können Dinge wie tun.Foo.without_default_order.order("created_at ASC")
In einigen Situationen liest es sich besser (vielleicht nicht genau diese Situation, aber ich hatte eine).Da
4.1
Sie verwenden könnenActiveRecord::QueryMethods#unscope
, um Standardbereich zu bekämpfen:Es ist derzeit möglich,
unscope
Dinge wie ::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.Aber bitte vermeiden
default_scope
Sie es trotzdem , wenn Sie können . Es ist zu deinem Besten.quelle
Mit der
with_exclusive_scope
Methode können Sie einen Standardbereich überschreiben . So:with_exclusive_scope
Dokumentationquelle
Rails 3 default_scope scheint nicht wie in Rails 2 überschrieben zu werden.
z.B
In meiner App mit PostgreSQL GEWINNT die Reihenfolge im Standardbereich. Ich entferne alle meine default_scopes und codiere sie explizit überall ein.
Fallstricke Rails3!
quelle
Bar.foos.reorder(:created_at => :asc)
Mit Rails 3+ können Sie eine Kombination aus unscoped und merge verwenden:
quelle
User.unscoped.where(email: "[email protected]")
Auf Rails 5.1+ (und vielleicht früher, aber ich habe getestet, dass es unter 5.1 funktioniert) ist es möglich, eine bestimmte Spalte zu entfernen. Dies ist imho die ideale Lösung, um eine Spalte
default_scope
auf eine Weise zu entfernen , die innerhalb eines benannten Bereichs verwendet werden kann. Im Fall der OPsdefault_scope
,Oder
Beides führt zu einer SQL-Abfrage, die nicht den ursprünglichen Bereich anwendet, aber alle anderen Bedingungen anwendet, die mit dem Arel zusammengeführt werden.
quelle
Nun, Sie können immer den alten Favoriten
find_by_sql
mit der vollständigen Abfrage verwenden. Zum Beispiel: Model.find_by_sql ("SELECT * FROM models WHERE id = 123")quelle