Problem 1
Betrachten wir das grundlegende Beispiel:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
Die Motivation, die Standardeinstellung published: true
festzulegen, könnte darin bestehen, sicherzustellen, dass Sie explizit sein müssen, wenn Sie unveröffentlichte (private) Beiträge anzeigen möchten. So weit, ist es gut.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Nun, das ist ziemlich genau das, was wir erwarten. Versuchen wir jetzt:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
Und da haben wir das erste große Problem mit dem Standardbereich:
=> default_scope wirkt sich auf Ihre Modellinitialisierung aus
In einer neu erstellten Instanz eines solchen Modells default_scope
wird das reflektiert. Während Sie vielleicht sicher sein wollten, nicht unveröffentlichte Beiträge nicht zufällig aufzulisten, erstellen Sie jetzt standardmäßig veröffentlichte Beiträge.
Problem 2
Betrachten Sie ein ausführlicheres Beispiel:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Lassen Sie uns die ersten Benutzerbeiträge erhalten:
2.1.1 :001 > User.first.posts
Post Load (0.3ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' AND "posts"."user_id" = ? [["user_id", 1]]
Dies sieht wie erwartet aus (stellen Sie sicher, dass Sie ganz nach rechts scrollen, um den Teil über die Benutzer-ID anzuzeigen).
Jetzt möchten wir die Liste aller Beiträge - einschließlich unveröffentlichter - erhalten, beispielsweise für die Ansicht des angemeldeten Benutzers. Sie werden feststellen, dass Sie den Effekt von "überschreiben" oder "rückgängig machen" müssen default_scope
. Nach einem kurzen Google werden Sie wahrscheinlich herausfinden unscoped
. Sehen Sie, was als nächstes passiert:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Unscoped entfernt ALLE Bereiche, die normalerweise für Ihre Auswahl gelten, einschließlich (aber nicht beschränkt auf) Zuordnungen.
Es gibt mehrere Möglichkeiten, die verschiedenen Effekte von zu überschreiben default_scope
. Das richtig zu machen wird sehr schnell kompliziert und ich würde argumentieren default_scope
, dass es eine sicherere Wahl wäre, das überhaupt nicht zu verwenden .
unscoped
stattdefault_scope
in Problem # 2default_scope
ist, wenn Sie möchten, dass etwas sortiert wird :default_scope { order(:name) }
.Ein weiterer Grund, den Sie nicht verwenden sollten,
default_scope
ist das Löschen einer Instanz eines Modells, die eine Beziehung von 1 zu vielen zumdefault_scope
Modell hatBetrachten Sie zum Beispiel:
Durch das Anrufen
user.destroy
werden alle Beiträge gelöschtpublished
, aber keine Beiträgeunpublished
. Daher löst die Datenbank eine Fremdschlüsselverletzung aus, da sie Datensätze enthält, die auf den Benutzer verweisen, den Sie entfernen möchten.quelle
default_scope wird häufig empfohlen, da es manchmal fälschlicherweise verwendet wird, um die Ergebnismenge einzuschränken. Eine gute Verwendung von default_scope besteht darin, die Ergebnismenge zu ordnen.
Ich würde mich von der Verwendung
where
in default_scope fernhalten und lieber einen Bereich dafür erstellen.quelle
default_scope
einzige enthältorder
. Dieses Verhalten vonunscoped
ist ziemlich unerwartet.Für mich ist nicht eine schlechte Idee , muss aber mit Vorsicht verwendet werden !. Es gibt einen Fall, in dem ich immer bestimmte Datensätze ausblenden wollte, wenn ein Feld festgelegt wurde.
default_scope
muß mit dem DB - Standardwert übereinstimmt (zB{ where(hidden_id: nil) }
)unscoped
Methode, mit der Sie dies vermeiden könnendefault_scope
Es wird also darauf ankommen und die wirklichen Bedürfnisse.
quelle
Ich finde
default_scope
es nur nützlich, einige Parameter so zu ordnen, dass sie in jeder Situation sindasc
oderdesc
in jeder Reihenfolge. Ansonsten vermeide ich es wie eine Pestquelle