Problema 1
Consideremos el ejemplo básico:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
La motivación para establecer el valor predeterminado published: true
podría ser asegurarse de tener que ser explícito cuando desee mostrar publicaciones no publicadas (privadas). Hasta aquí todo bien.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Bueno, esto es más o menos lo que esperamos. Ahora intentemos:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
Y ahí tenemos el primer gran problema con el alcance predeterminado:
=> default_scope afectará la inicialización de su modelo
En una instancia recién creada de dicho modelo, default_scope
se reflejará. Entonces, si bien es posible que haya querido asegurarse de no enumerar publicaciones no publicadas por casualidad, ahora está creando las publicadas de forma predeterminada.
Problema 2
Considere un ejemplo más elaborado:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Permite obtener las primeras publicaciones de los usuarios:
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]]
Esto se ve como se esperaba (asegúrese de desplazarse completamente hacia la derecha para ver la parte sobre user_id).
Ahora queremos obtener la lista de todas las publicaciones, incluidas las no publicadas, por ejemplo, para la vista del usuario conectado. Te darás cuenta de que tienes que 'sobrescribir' o 'deshacer' el efecto de default_scope
. Después de un rápido google, es probable que lo descubras unscoped
. Mira lo que pasa después:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Sin ámbito elimina TODOS los ámbitos que normalmente podrían aplicarse a su selección, incluidas (entre otras) las asociaciones.
Hay varias formas de sobrescribir los diferentes efectos de default_scope
. Hacer eso bien se complica muy rápidamente y argumentaría que no usar el default_scope
en primer lugar, sería una opción más segura.