Das Starten von Rails 4 Model.scoped
ist jetzt veraltet.
DEPRECATION WARNING: Model.scoped is deprecated. Please use Model.all instead.
Aber gibt es einen Unterschied in Model.scoped
und Model.all
, das heißt, scoped.scoped
gibt einen Rahmen, während all.all
läuft die Abfrage.
Auf Schienen 3:
> Model.scoped.scoped.is_a?(ActiveRecord::Relation)
=> true
Auf Schienen 4:
> Model.all.all.is_a?(ActiveRecord::Relation)
DEPRECATION WARNING: Relation#all is deprecated. If you want to eager-load a relation, you can call #load (e.g. `Post.where(published: true).load`). If you want to get an array of records from a relation, you can call #to_a (e.g. `Post.where(published: true).to_a`).
=> false
Es gibt Anwendungsfälle in Bibliotheken / Anliegen, die zurückkehren, scoped
wenn eine Bedingung besteht, etwas oder nichts zu tun, wie zum Beispiel:
module AmongConcern
extend ActiveSupport::Concern
module ClassMethods
def among(ids)
return scoped if ids.blank?
where(id: ids)
end
end
end
Wenn Sie dies ändern scoped
, all
treten zufällige Probleme auf, je nachdem, wo das among
in der Bereichskette verwendet wurde. Zum Beispiel Model.where(some: value).among(ids)
würde die Abfrage ausgeführt, anstatt einen Bereich zurückzugeben.
Was ich will, ist eine idempotente Methode ActiveRecord::Relation
, die einfach einen Bereich zurückgibt.
Was soll ich hier machen?
all
führt die Abfrage aus" nicht nur ein Artefakt der Konsole ist? Die Quelle schlägt vor, dass es gut funktionieren sollte.all
vonscoping/named.rb
, richtig? Und dasall
vonscoping/named.rb
ist, AFAIK, wasModel.all
verwendet.Antworten:
Es scheint, dass dies
where(nil)
ein echter Ersatz fürscoped
Rails 3 und 4 ist. :(quelle
load
.load
WENN Sie eifrig laden möchten, und in jedem Fall nimmt es einen Parameter (Bedingung), so scheint jetztwhere(nil)
(odertrue
oder{}
oder1
) der beste Ersatz fürscoped
user.active_section.scoped.uniq(false)
funktioniertuser.active_section.all.uniq(false)
oderuser.active_section.where(nil).uniq(false)
nicht.Auf Rails 4.1 (Beta 1) funktioniert Folgendes:
Es scheint also, dass dieses Problem behoben und in 4.1.0
Model.scoped
vollständig entfernt wurde.quelle
where(nil)
bis 4.0.x nicht mehr unterstützt wird ...if ActiveRecord::VERSION::MAJOR == 3 then Model.scoped else Model.all end
?Wie in einem der Kommentare erwähnt,
all
soll ein Bereich gemäß den Dokumenten zurückgegeben werden .Die Dokumente sind korrekt - es wird zwar eine ActiveRecord :: Relation zurückgegeben, Sie müssen jedoch ein Semikolon verwenden, wenn Sie es in der Konsole anzeigen möchten:
pry(main)> u = User.all; pry(main)> u.class => ActiveRecord::Relation::ActiveRecord_Relation_User
quelle
User.all.all;
Sie es und Sie erhalten die gleiche Warnung. Leider wird es nicht behoben, bis Rails 4.x oder sogar Rails 5. github.com/rails/rails/issues/12756Zusätzlich zur Verwendung können
where(nil)
Sie auch anrufen,clone
wenn Sie wissen, dassself
es sich um eine Beziehung handelt, und das identische Verhalten beim Aufrufenscoped
ohne Argumente erhalten, ohne die Warnung vor der Ablehnung.BEARBEITEN
Ich verwende diesen Code jetzt als Ersatz für,
scoped
da ich ihn nicht gernewhere(nil)
überall verwende, um den aktuellen Bereich zu erreichen:# config/initializers/scoped.rb class ActiveRecord::Base # do things the modern way and silence Rails 4 deprecation warnings def self.scoped(options=nil) options ? where(nil).apply_finder_options(options, true) : where(nil) end end
Ich verstehe nicht, warum die AR-Autoren etwas Ähnliches nicht hätten tun können, da das OP darauf hinweist
all
undscoped
sich nicht gleich verhält.quelle
clone
Modellklasse aufrufen . (zBModel.clone
)scoped
arbeitete sowohl an Modellklassen als auch an Beziehungen.