Problema 1
Consideriamo l'esempio di base:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
La motivazione per rendere l'impostazione predefinita published: true
, potrebbe essere quella di assicurarsi di essere esplicitati quando si desidera mostrare post (privati) non pubblicati. Fin qui tutto bene.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Bene, questo è praticamente ciò che ci aspettiamo. Ora proviamo:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
E lì abbiamo il primo grosso problema con ambito predefinito:
=> default_scope influenzerà l'inizializzazione del modello
In un'istanza appena creata di tale modello, default_scope
verrà riflesso. Quindi, anche se potresti voler essere sicuro di non elencare i messaggi non pubblicati per caso, ora stai creando quelli pubblicati per impostazione predefinita.
Problema 2
Considera un esempio più elaborato:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Consente di ottenere i post dei primi utenti:
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]]
Sembra previsto (assicurati di scorrere fino a destra per vedere la parte su user_id).
Ora vogliamo ottenere l'elenco di tutti i post - incluso non pubblicato - diciamo per la vista dell'utente che ha effettuato l'accesso. Ti renderai conto che devi "sovrascrivere" o "annullare" l'effetto di default_scope
. Dopo un rapido google, probabilmente lo scoprirai unscoped
. Guarda cosa succede dopo:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Unscoped rimuove TUTTI gli ambiti che normalmente potrebbero applicarsi alla tua selezione, incluse (ma non limitate a) associazioni.
Esistono diversi modi per sovrascrivere i diversi effetti di default_scope
. Ottenere questo diritto diventa complicato molto rapidamente e direi che non usare default_scope
il primo, sarebbe una scelta più sicura.