Comment puis-je désactiver une validation et des rappels dans un modèle dérivé de STI de rails?
Un modèle
class BaseModel < ActiveRecord::Base
validates_presence_of :parent_id
before_save :frobnicate_widgets
end
et un modèle dérivé (la table sous-jacente a une type
champ, ce qui est simple rails STI)
class DerivedModel < BaseModel
end
DerivedModel
de bonne OO mode hériter de tous les comportements de BaseModel
y compris la validates_presence_of :parent_id
. Je voudrais tourner la validation off pour DerivedModel
et de prévenir les méthodes de rappel de cuisson, de préférence sans modifier ou autrement rupture BaseModel
Ce qui est le plus simple et le plus robuste de la façon de le faire?
source d'informationauteur Orion Edwards
Vous devez vous connecter pour publier un commentaire.
J'aime utiliser le modèle suivant:
Ce serait bien si les rails fourni un skip_validation méthode pour contourner ce problème, mais ce modèle fonctionne et gère les interactions complexes.
Comme une variation de la réponse par @Jacob Rothstein, vous pouvez créer une méthode dans parent:
L'avantage de cette approche est de vous pas besoin de créer de multiples méthodes pour chaque nom de colonne, vous devez désactiver la validation pour les Enfants de la classe.
De fouiller dans la source (je suis actuellement sur les rails 1.2.6), les rappels sont relativement simples.
Il s'avère que le
before_validation_on_create
before_save
etc méthodes, si ce n'est invoqué des arguments, sera de retour le tableau qui détient tous les rappels attribué au "callback " site"Pour effacer le before_save, vous pouvez simplement faire
et il semble fonctionner
D'une façon plus propre est celle-ci:
Ou vous pouvez aussi l'utiliser de cette façon:
Ainsi, l'unicité de la validation est effectuée si l'instance de la classe de modèle est
Parent
.Child
estChild
et diffère deParent
.Parent
estParent
et est le même queParent
.Encore farfouillé dans la source, il semble que les validations peut être exécutée sur tous les sauver, ou des mises à jour/crée seulement. Il correspond à
:validate
=> toutes les sauvegardes:validate_on_create
=> créations uniquement:validate_on_update
=> uniquement les mises à jourPour les désactiver, vous pouvez utiliser
write_inheritable_attribute
comme ceci:Ici est une légère variation de RubyDev est le fait que j'ai utilisé dans mongoid 3.
Il a travaillé très bien pour moi jusqu'à présent.
Depuis rails 3.0, vous pouvez également accéder à la
validators
méthode de classe à manipuler obtenir une liste de toutes les validations. Cependant, vous ne pouvez pas manipuler l'ensemble des validations par le biais de ce Tableau.À moins que des rails 5.0 vous semblent pourtant être capable de manipuler les
_validators
(sans-papiers) méthode.Utilisant cette méthode, vous pouvez modifier les validations dans la sous-classe, comme par exemple:
Alors que celui-ci utilise une méthode non documentée, est a l'avantage de ne pas nécessiter la superclasse de savoir quelque chose au sujet de l'enfant est mise en œuvre.