2010-01-07 3 views
5

J'utilise la machine d'état rubyist-aasm pour gérer les différents états de mon objet Event (événement initialisé, événement discuté, événement publié, etc.). J'ai ajouté des gardes pour empêcher les changements d'état lorsque certaines conditions ne sont pas remplies.Gestion des erreurs Rails avec la machine d'état AASM

Tout cela fonctionne très bien, mais il ne montre aucune erreur quand un changement d'état a été rejeté par le garde. Toute idée de comment je peux voir l'état n'a pas changé? Je pourrais vérifier les états manuellement mais cela ressemble à une solution laide.

aasm_state :firststate 
aasm_state :secondstate 

aasm_event :approve do 
    transitions :to => :secondstate, :from => [:firststate], :guard => :has_a_price? 
end 

def has_a_price? 
    self.price.present? 
end 

Répondre

0

Je sais dans rubyist-aasm 2.0.2 vous pouvez appeler ajouter '!' à l'appel de la méthode de transition qui retournera false si la transition a échoué. Alors disons que vous avez une méthode de contrôleur nommée approuver:

def approve 
    @event = Event.find params[:id] 

    if @event.approve! 
    # transition occurred 
    else 
    # handle the failed transition (flash or errors) 
    end 
end 

Faites-moi savoir ce que vous en pensez?

+0

Merci, cela fonctionnerait dans le contrôleur, mais je voudrais garder ces choses dans le modèle. Avec votre solution, je pourrais toujours utiliser la transition dans un autre modèle sans passer la validation. – Cimm

+1

Ah, d'accord. IMO la garde n'est pas vraiment une erreur de validation en ce qui concerne le modèle AR, cependant, c'est un garde qui protège simplement la transition de se produire sur la machine d'état, je serais personnellement heureux d'appeler le! méthode (dans un autre modèle ou un contrôleur) et en vérifiant le retour. Vous ne pouvez pas "voir" quelque chose si vous ne le demandez pas correctement? Je pourrais me tromper complètement ici, donc je serai heureux de voir si d'autres solutions surgissent. Si vous voulez vraiment aussi une erreur de validation, vous pouvez ajouter quelque chose comme validates_presence_of: price,: if => "self.second_state?" – tsdbrown

2

Avec SimpleStateMachine vous pouvez garder les transitions d'état en ajoutant des erreurs:

def approve 
    errors.add(:price, 'Invalid') if price.blank? 
end 
event :approve, :firststate => :secondstate 

Bien que dans ce cas, le prix étant présent n'est pas lié à l'événement il suffirait de le faire:

validates_presence_of :price, :if => "self.second_state?" 
event :approve, :firststate => :secondstate