Ruby state_machine gem - test validates_presence_of
I've added the state_machine support to my Post class:
state_machine :state, :initial => :draft do
event :publish do
transition :draft => :published
end
state :draft do
end
state :published do
end
end
In ERB, a new Post indicates that it can be published:
>> k=Job.new => #<Job id: nil, title: nil> >> k.can_publish? => true
However, it can't actually be published:
>> k.publish! StateMachine::InvalidTransition: Cannot transition state via :publish from :draft
As it turns out, the class' validates_presence_of :title is preventing the change of state. The save!() method fails because :title is required. Unfortunately, the InvalidTransition error is a little decep开发者_Python百科tive.
I'm concerned that this error message will interfere with the View layer's handling of missing fields (:title in my example). Is there a way to test the validates_presence_of in the can_publish? method?
** edit **
I found the following in the StateMachine::Machine documentation:
can_park?(requirements = {}) - Checks whether the "park" event can be fired given the current state of the object. This will not run validations in ORM integrations. To check whether an event can fire and passes validations, use event attributes (e.g. state_event) as described in the "Events" documentation of each ORM integration.
Now if I can just determine what 'use event attributes (e.g. state_event) as described in the "Events" documentation of each ORM integration.' means in the scope of ActiveRecord.
The issue appears to be that your object is not passing standard ActiveRecord validation; i.e., if you do:
k.valid?
you'll find that the object's state is invalid. Once you get the object into a valid state as far as ActiveRecord is concerned then state_machine will allow it to change states.
To check and see what validation errors there are, use:
k.valid?
k.errors.each {|field, message| puts "#{field}: #{message}"}
and look at the output. Fix those issues and then try state transitions again.
精彩评论