aasm after callback with argument

7.9k Views Asked by At

I'm using the aasm (formerly acts_as_state_machine) gem in my rails 4 application. I have something like this on my Post model

  ...
  aasm column: :state do
    state :pending_approval, initial: true
    state :active
    state :pending_removal

    event :accept_approval, :after => Proc.new { |user| binding.pry } do
      transitions from: :pending_approval, to: :active
    end
  end
  ...

When I call @post.accept_approval!(:active, current_user) and the after callback gets triggered, in my console I can inspect what user is (that was passed into the Proc) and it's nil!

What's going on here? What is the correct way to call this transition?

4

There are 4 best solutions below

0
On

Look aasm docs in section callbacks.

...
  aasm column: :state do
    state :pending_approval, initial: true
    state :active
    state :pending_removal

    after_all_transition :log_all_events

    event :accept_approval, after: :log_approval do
      transitions from: :pending_approval, to: :active
    end
  end
  ...
  del log_all_events(user)
    logger.debug "aasm #{aasm.current_event} from #{user}"
  end

  def log_approval(user)
    logger.debug "aasm log_aproove from #{user}"
  end

You can call events with needed params:

  @post.accept_approval! current_user
1
On

It works in the current version (4.3.0):

event :finish do
  before do |user|
    # do something with user
  end

  transitions from: :active, to: :finished
end
0
On
event :accept_approval do
  transitions from: :pending_approval, to: :active
end

post.accept_approval!{post.set_approvaler(current_user)}

block to bang method will be call after transition success, if any activerecord operation, it will be wrap into transition transaction, your can require a lock to prevent concurrency problem with option requires_lock: true.

0
On

Move :after to the transitions sections, such that:

event :accept_approval do
  transitions from: :pending_approval, 
    to: :active,
    :after => Proc.new { |user| binding.pry }
end

Then call it as @post.accept_approval!(current_user)