thisismydesign
thisismydesign

Reputation: 25102

Ruby AASM: trigger callbacks on model update

AASM callbacks are bypassed when updating model fields directly. This can be disabled by setting the no_direct_assignment flag, but this will break other integrations, such as a simple update via active_admin.

Is there a way to allow model updates to AASM state fields and make them behave as state transitions?

I.e. developer.update!(state: :hired) to behave the same as developer.hired!.

Upvotes: 1

Views: 206

Answers (1)

thisismydesign
thisismydesign

Reputation: 25102

active_admin offers a hacky solution to work with AASM.

I came up with a model-agnostic way to turn direct state updates into transitions. This can be used in a regular controller as well, but here's an example working with active_admin

ActiveAdmin.register MyModel do
  controller do
    def update
      model_key = resource_class.model_name.param_key
      aasm_columns = resource_class.aasm.events.map{ |event| event.state_machine.config.column.to_s }.uniq
      states_to_update = params[model_key].keys & aasm_columns
      events = states_to_update.map { |state_column| params[model_key].delete(state_column) }

      if events.any?
        record = resource_class.find(params[:id])

        ActiveRecord::Base.transaction do
          events.each { |event| record.send("#{event}!") }

          super
        end
      else
        super
      end
    end
  end
end

Upvotes: 1

Related Questions