Problème 1
Prenons l'exemple de base:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
end
La motivation pour faire la valeur par défaut published: true
, peut être de vous assurer que vous devez être explicite lorsque vous souhaitez afficher des messages non publiés (privés). Jusqu'ici tout va bien.
2.1.1 :001 > Post.all
Post Load (0.2ms) SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't'
Eh bien, c'est à peu près ce à quoi nous nous attendons. Essayons maintenant:
2.1.1 :004 > Post.new
=> #<Post id: nil, title: nil, published: true, created_at: nil, updated_at: nil>
Et là, nous avons le premier gros problème avec la portée par défaut:
=> default_scope affectera l'initialisation de votre modèle
Dans une instance nouvellement créée d'un tel modèle, le default_scope
sera reflété. Ainsi, bien que vous ayez peut-être voulu être sûr de ne pas lister les articles non publiés par hasard, vous créez maintenant des articles publiés par défaut.
Problème 2
Prenons un exemple plus élaboré:
class Post < ActiveRecord::Base
default_scope { where(published: true) }
belongs_to :user
end
class User < ActiveRecord::Base
has_many :posts
end
Permet d'obtenir les premiers messages des utilisateurs:
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]]
Cela ressemble à ce que vous attendez (assurez-vous de faire défiler tout le chemin vers la droite pour voir la partie concernant le user_id).
Maintenant, nous voulons obtenir la liste de tous les messages - non publiés inclus - par exemple pour la vue de l'utilisateur connecté. Vous réaliserez que vous devez «écraser» ou «annuler» l'effet de default_scope
. Après un rapide google, vous découvrirez probablement unscoped
. Voyez ce qui se passe ensuite:
2.1.1 :002 > User.first.posts.unscoped
Post Load (0.2ms) SELECT "posts".* FROM "posts"
=> Unscoped supprime TOUTES les étendues qui pourraient normalement s'appliquer à votre sélection, y compris (mais sans s'y limiter) les associations.
Il existe plusieurs façons d'écraser les différents effets du default_scope
. Obtenir ce droit se complique très rapidement et je dirais que ne pas utiliser le, default_scope
en premier lieu, serait un choix plus sûr.