2010-01-18 7 views
5

J'ai une table avec une colonne appelée lifecycle_id, et une autre appelée lifecycle_change_reason. lifeycle_id est normalement modifié automatiquement par le système en fonction d'autres facteurs, mais certains utilisateurs ont la possibilité de modifier le cycle de vie manuellement. si c'est le cas, je voudrais leur demander de fournir une raison pour le changement, mais je ne veux pas exiger ce champ à un autre moment. Quelqu'un at-il une suggestion sur la façon dont je peux effectuer ce type de validation?comment puis-je valider la présence d'un champ uniquement si un autre champ a été édité dans des rails?

thx :)

C

Répondre

0

Je peux voir un couple de différentes façons. Je pense le mieux serait d'ajouter un autre champ à la table appelée quelque chose comme lifecycle_id_original. Ensuite, votre modèle comprendrait code comme ceci:

class Member < ActiveRecord::Base 
    belongs_to :lifecycle 

    validates :lifecycle_change_reason, :if => :lifecycle_changed? 

    before_save :reset_original_lifecycle 

    protected 

    def lifecycle_changed? 
    self.life_cycle_id != self.lifecycle_id_original && !self.lifecycle_id_original.nil? 
    end 

    def reset_original_lifecycle 
    self.lifecycle_id_original = self.lifecycle_id 
    end 
end 

Lorsque l'objet (membre dans cet exemple) est validée, lifecycle_change_reason ne seront requis que lorsque l'original et lifecycle_id ne sont pas identiques. Une valeur nulle est également autorisée pour l'original, car c'est ce que ce sera lors de la création d'un enregistrement.

Ensuite, quand il est sauvegardé, le "original" est réglé pour correspondre à lifecycle_id, de sorte que le prochain cycle de mise à jour fonctionnera correctement.

Ce n'est pas aussi propre que je le voudrais. Ma première pensée a été d'utiliser un attr_accessor afin que le doublon ne soit pas stocké dans le DB tout le temps, mais cela aurait signifié de définir cette valeur chaque fois qu'un enregistrement est chargé. Je ne connais aucun rappel de style on_load pour les modèles ActiveRecord.

-1

Cela semble être ce à quoi sert le contrôleur. Je réalise que les gens veulent pousser la logique vers les modèles, et pour de bonnes raisons, mais soyons pragmatiques ici: si votre système change automatiquement cette valeur, et qu'il n'y a qu'un seul point dans votre système où quelqu'un peut le changer manuellement, il le fait pas, à mon avis, introduire toute cette complexité pour simplement imposer l'existence d'une raison dans votre contrôleur avec quelque chose de simple comme:

if params[:object_name][:life_cycle_id] != @object.life_cycle_id && params[:object_name][:life_cycle_change_reason].blank? 
    flash[:error] = "You must enter a reason for changing the life cycle." 
    redirect_to :back and return false # or whatever 
end 
+0

le problème avec ceci est que vous n'obtenez pas toute la gestion des erreurs de validation agréable dans la forme. –

+0

Sûrement vous savez comment faire cela aussi: @ object.errors.add (: life_cycle_change_reason, "doit être fourni.") Simple. – adriandz

Questions connexes