ruby-on-railsstateaasm

Ruby on rails AASM Change transition on button click


My question is very simple: how can I change aasm transitions on button click? What should I put in my view?

I have two buttons: Approve and Reject. My states look like this:

  aasm :column => 'state' do
    state :pending, :initial => true
    state :approved
    state :rejected

    event :approve do
      transitions :to => :approved, :from => [:pending]
    end

    event :reject do
      transitions :to => :rejected, :from => [:pending]
    end
  end

UPDATE: My params are these:

{"utf8"=>"✓", "_method"=>"put", "authenticity_token"...", "commit"=>"APP", "id"=>"65"}.

And this is how I access action from the view:

= form_for([:admin, shop], method: :put, data: { confirm: "You sure?" }) do |f|
  = f.submit "Approve", :controller => :shops, :action => :approve

My controller code:

def approve
  @shop = Shop.find(params[:id])
  @shop.approve!
end

Routes:

namespace :admin do
  get "shops/:id/approve" => "shops#approve"

Solution

  • As mentioned by Srikanth, you'll want to send your request to your controller, however, instead of using a form outright, I'd recommend using a button_to as follows:

    <%= button_to "Approve", admin_shops_approve_path(shop.id), method: :put %>
    <%= button_to "Disapprove", admin_shops_disapprove_path(shop.id), method: :put %>
    

    This will send a request to your controller. You already seem to be doing this, but to clarify, you'll want to use the following:

    #config/routes.rb
    namespace :admin do
       resources :shops do
          put :approve #-> domain.com/admin/shops/:id/approve
          put :disapprove #-> domain.com/admin/shops/:id/disapprove
       end
    end
    
    #app/controllers/admin/shops_controller.rb
    class Admin::ShopsController < ApplicationController
       before_action, :set_shop
    
       def approve
          @shop.approve!
       end
    
       def disapprove
          @shop.disapprove!
       end
    
       private
    
       def set_shop
          @shop = Shop.find params[:id]
       end
    end
    

    This will give you an efficient way to send the required data to your form, triggering the AASM process as a result.