J'ai Rails modèle polymorphe et je veux appliquer différentes validations selon classe associée.Comment appliquer une règle de validation différente selon le type d'association polymorphe (Rails)?
Comment appliquer une règle de validation différente selon le type d'association polymorphe (Rails)?
Répondre
Le nom de la classe est dans la colonne _type
par exemple dans la configuration suivante:
class Comment
belongs_to :commentable, :polymorphic => true
end
class Post
has_many :comments, :as => :commentable
end
la classe de commentaires va avoir les commentable_id
et commentable_type
champs. est le nom de classe et commentable_id
est la clé étrangère. Si vous vouliez une validation par commentaire des commentaires post-spécifiques, vous pouvez faire quelque chose comme ceci:
validate :post_comments_are_long_enough
def post_comments_are_long_enough
if self.commentable_type == "Post" && self.body.size < 10
@errors.add_to_base "Comment should be 10 characters"
end
end
OU, et je pense que j'aime mieux:
validates_length_of :body, :mimimum => 10, :if => :is_post?
def is_post?
self.commentable_type == "Post"
end
si vous avez plusieurs validations, je recommande la syntaxe suivante:
with_options :if => :is_post? do |o|
o.validates_length_of :body, :minimum => 10
o.validates_length_of :body, :maximum => 100
end
La méthode validates_associated est ce que vous avez besoin. Il suffit de lier cette méthode au modèle polymorphe et de vérifier si les modèles associés sont valides.
class Comment < ActiveRecord::Base
belongs_to :commentable, :polymorphic => true
validates_associated :commentable
end
class Post < ActiveRecord::Base
has_many :comments, as: commentable
validates_length_of :body, :minimum => 10
validates_length_of :body, :maximum => 100
end
Je reçois cette erreur undefined method' body 'pour –
@KickButtowski Peut-être parce que vous n'avez pas l'attribut 'body' sur votre modèle? – Guillaume
C'est la partie de merde. Impossible d'accéder aux attributs depuis l'intérieur du modèle polymorphe. "méthode non définie' itemable_type 'pour # " –
BlackTea
La vie serait parfaite sinon ... :( – BlackTea
si vous écrivez le code ci-dessus directement dans votre classe qui échouerait, il ne serait disponible que pour un instance, pas la classe Ajoutez le code 'define_method' dans une méthode d'instance et il devrait passer –