Best way to extend restful_authentication AASM state

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

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

+1


source to share


1 answer


Adding state to AASM consists of creating a new State object, which is then added to the 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

      

It should be noted that it will not allow you to override the state after you set it. If a state with the same name is set again, the create_state method simply ignores it. To solve 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 reviewing the state, you should be fine. But if you want to completely remove the state, you must also define the method defined in the body of the aasm_state method. This should be possible by calling something like:



undef_method :name

      

The situation should be the same as with events (just use "events" instead of "states" in your code). Ideally, make it a method of the User model class, which overrides the methods defined in the 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 may be wrong. This code is untested, I just figured it out by looking at the AASM source code.

+1


source







All Articles