Mirror318
Mirror318

Reputation: 12663

ActiveAdmin custom resource action (view and action)

I'm trying to make a form to edit one attribute of a resource. It seems like such a simple thing, but I'm dying out here. I have this code for processing it:

  member_action :revoke, method: :put do
    resource.update(suspended_at: params[:suspended_at])
    redirect_to resource_path, notice: 'Subscription revoked!'
  end

But where/how do I actually make the form?

I have tried this code:

  ActiveAdmin.register_page "Revoke" do
    belongs_to :payment_subscription, parent_class: Payment::Subscription
    content do
      semantic_form_for Payment::Subscription.find(params[:id]) do
        f.inputs do
          f.input :suspended_at, as: :datepicker, datepicker_options: { max_date: Date.today.iso8601 }
        end
        f.actions
      end
    end
  end

But it's throwing an error saying Could not find Subscription in active_admin, and honestly I don't know if I'm even in the right direction.

Upvotes: 4

Views: 1891

Answers (2)

Mirror318
Mirror318

Reputation: 12663

Ok I figured something out. Here's the full setup for future reference:


Adding a link to the page that will contain the form:

  action_item :revoke, only: :show, if: -> { !resource.state.suspended? } do
    link_to('Revoke', revoke_active_admin_payment_subscription_path(resource), method: :get)
  end

And the routes for GET (to render the form) and PUT (to update the model):

  member_action :revoke, method: [:get, :put] do
    if request.put?
      resource.model.update(suspended_at: params[:payment_subscription][:suspended_at])
      redirect_to resource_path, notice: 'Subscription revoked!'
    else
      render :revoke, locals: { resource: resource }
    end
  end

The GET will look for a view called revoke.html.arb within the views/active_admin directory:

active_admin_form_for resource.model,
  url: revoke_active_admin_payment_subscription_path(resource),
  method: :put do |f|
  f.inputs do
    f.input :suspended_at, as: :datepicker, datepicker_options: { max_date: Date.today.iso8601 }
  end
  f.actions
end

Upvotes: 2

Sjors Branderhorst
Sjors Branderhorst

Reputation: 2182

I think it is simpler to set it up without the separate Page. You can have 2 member_action blocks in the resource file. One would be method :get, the other method :post e.g.:

member_action :revoke, :method => :get do
  # this will render the template, if you don't know where to put it,
  # the rails log will tell you where rails is looking for it
end

Rake routes will help you find the spelling for the path helper, you will need this for the :action attribute . Put your custom form in the template.arb (give it the .arb extension) you put your custom form:

form(:method => :post, :action => the_path_helper_that_you_just_saw_in_rake_routes_path) do # dont forget _path at   the end
  input(:type => :hidden, :name => 'authenticity_token', :value => form_authenticity_token)
 # your custom inputs
  input :type => :submit, :value => 'Revoke!'
end

Then you will have to catch the POST in the other :member_action:

member_action :revoke, :method => :post do
  # I stub it with this, to see if the POST will reach
  # raise params.inspect
  # your logic
  if true
    # flash message
    redirect_to where_you_want and return
  else 
    # flash message
    # either
    #   render the get member_action
    # or
    # redirect_to the_get_route and return
  end
end

Upvotes: 2

Related Questions