views:

484

answers:

1

I recently had to extend the aasm states for the latest version of restful_authentication (github) in one of my apps. I removed the "include Authorization::AasmRoles", copied the existing states and events from the plugin and made the changes necessary to support an additional "published" state on my account model.

Does anyone have a cleaner way to handle this? I.e. just override the state events? I was able to add new events using the plugin as is, however I wasn't able to just override the state events already in restful_auth so I had to remove the include and write it out myself using it as a starting point.

+1  A: 

Adding of a state in AASM consists of creating a new State object, which is then added to AASM::StateMachine[User].states array, which looks like this:

def create_state(name, options)
 @states << AASM::SupportingClasses::State.new(name, options) unless @states.include?(name)
end

The thing to notice here is that it won't allow to override a state once it is set. If the state with the same name is set again, create_state method just ignores it. To slove this problem, you can use something like this in your User model:

# this will remove the state with name :name from the states array 
states = AASM::StateMachine[self].states
states.delete(states.find{ |s| s == :name })
# ... so we can define the state here again
aasm_state :name ...

If you are just redefining the state you should be fine now. But if you want to remove the state entirely, you should undefine the method defined in the body of aasm_state method, too. It should be possible with calling something like:

undef_method :name

The situation should be the same with events (just use "events" instead of "states" in the code). Ideally, make it User model's class method that overrides methods defined in AASM module. In the case of states it would look like this:

def aasm_state(name, options={})
  states = AASM::StateMachine[self].states
  states.delete(states.find{ |s| s == name.to_sym })
  super(name, options)
end

Warning: I might not be right. This code is untested, I just figured it out by looking into the source code of AASM.

Milan Novota