Le remplacement d'un des Rails default_scope
Si j'ai un ActiveRecord::Base de modèle avec un défaut-portée:
class Foo < ActiveRecord::Base
default_scope :conditions => ["bar = ?",bar]
end
Est-il possible de faire un Foo.find
sans à l'aide de la default_scope
conditions? En d'autres termes, pouvez-vous remplacer une valeur par défaut portée?
J'aurais pensé que l'utilisation de "par défaut" dans le nom suggère qu'il était substituables, autrement ce serait quelque chose comme global_scope
, droit?
Vous devez vous connecter pour publier un commentaire.
Réponse courte: Ne pas utiliser
default_scope
sauf si vous devez vraiment. Vous serez probablement mieux avec nommée étendues. Cela étant dit, vous pouvez utiliserwith_exclusive_scope
pour remplacer l'étendue par défaut si vous en avez besoin.Ont un coup d'oeil à cette question pour plus de détails.
default_scope
peut sembler une bonne idée, mais probablement à l'origine de plusieurs maux de tête pendant la durée de vie de votre application.default_scope
?with_exclusive_scope
a été supprimé dans rails 3default_scope
est un excellent outil et il y a des situations où vous pourriez une autre façon, maisdefault_scope
son juste la bonne chose à faire. Par exemple, lorsque vous avez unProduct
modèle qui dispose d'uninactive
drapeau, la définition d'unedefault_scope { where inactive: false }
est la meilleure chose à faire, puisque 99% des cas, vous ne voulez pas afficher un produit inactif. Ensuite, vous appelez simplementunscoped
sur les 1% restants des cas, ce qui est probablement un panneau d'administration.Dans Rails 3:
def self.random; unscoped.order('rand()'); end
non délimité supprime TOUS les composants de sql avant elle, et pas seulement ce qui est répertorié sous default_scope. Bien que, techniquement, une réponse correcte, veillez à l'utiliserunstopped
unscoped
ne pas annulerdefault_scope
!!!unscoped
quand il peut suivre directement un modèle, par exempleFoo.unscoped.blah()
est ok, mais jamaisFoo.blah().unscoped
.Si vous avez besoin de changer l'ordre défini dans
default_scope
, vous pouvez utiliser leréorganiser
méthode.exécute la requête SQL suivante:
scope :without_default_order, -> { reorder("") }
et vous pouvez faire des choses commeFoo.without_default_order.order("created_at ASC")
Dans certaines situations, il se lit mieux (peut-être pas cette situation exacte, mais j'en avais un).Depuis
4.1
vous pouvez utiliserActiveRecord::QueryMethods#unscope
de lutte contre étendue par défaut:Il est actuellement possible de
unscope
des trucs comme::where, :select, :group, :order, :lock, :limit, :offset, :joins, :includes, :from, :readonly, :having
.Mais encore veuillez éviter d'utiliser des
default_scope
si vous pouvez. C'est pour votre propre bien.Vous pouvez remplacer une valeur par défaut de la portée à l'aide de la
with_exclusive_scope
méthode. Donc:with_exclusive_scope
documentationRails 3 default_scope ne semble pas obtenir substituée comme il l'a fait dans les Rails 2.
par exemple
Dans mon application, l'utilisation de PostgreSQL, la commande par défaut dans le champ d'application de VICTOIRES. Je suis en supprimant tous mes default_scopes et de codage dans expressément partout.
Piège Rails3!
Bar.foos.reorder(:created_at => :asc)
Avec Rails 3+ vous pouvez utiliser une combinaison de non délimité et de fusion:
User.unscoped.where(email: "[email protected]")
Bien, vous pouvez toujours utiliser l'ancien favori de temps
find_by_sql
avec la requête complète.Par exemple:
De modèle.find_by_sql("SELECT * from modèles where id=123")
Sur des Rails 5.1+ (et peut-être plus tôt, mais je l'ai testé il fonctionne sur 5.1) il est possible de unscope une colonne spécifique, qui à mon humble avis est la solution idéale pour le retrait d'un
default_scope
dans un mode qui peut être utilisé à l'intérieur d'une étendue nommée. Dans le cas de la Fpodefault_scope
,Ou
Sera à la fois du résultat d'une requête sql qui ne s'applique pas à la portée initiale, mais ne s'appliquent quelles que soient les autres conditions sont fusionnés dans l'arel.