Skip to content

How To: Add Custom Action

coezbek edited this page Dec 8, 2021 · 7 revisions

There are at least 3 places where you might want to add actions in Trestle:

  • Table actions: Are shown in the ActionColumn (usually right-most) and act on the current row/member
  • Form actions: Shown in the top right above the form in edit/new and act upon the current instance/member
  • Collection actions: Show in the top right above the table and are independent of a particular object instance (thus collection action)

Just like in the normal Rails framework, adding a custom action requires:

  • Adding a route
  • Adding an action to the controller
  • Linking to that action

Example 1: Adding actions to form and table (Member action)

Trestle.resource(:missiles) do
  # ...
  form do |missile|
    # ...
    sidebar do
      link_to('Launch!', admin.path(:launch, id: instance.id), method: :post, class: "btn btn-danger btn-block")
    end
  end

  table do
    # ...
    actions do |toolbar, instance, admin|
      toolbar.edit if admin && admin.actions.include?(:edit)
      toolbar.delete if admin && admin.actions.include?(:destroy)
      toolbar.link 'Launch', instance, action: :launch, method: :post, style: :primary, icon: "fa fa-check" if instance.pending?
    end
  end

  controller do
    def launch
      missile = admin.find_instance(params)
      LaunchMissileJob.perform_later(missile_id: missile.id)
      flash[:message] = "Missile will be launched soon"
      redirect_to admin.path(:show, id: missile)
    end
  end

  routes do
    post :launch, on: :member
  end
end

Example 2: Adding a collection action

Trestle.resource(:missiles) do
  # ...
  controller do
    def index
      toolbar(:primary) do |t|
        t.link("Launch all", admin.path(:launch_all))
      end
    end

    def launch_all
      # ...
    end
  end

  routes do
    get :launch_all, on: :collection
  end
end

Source: Issue #186

Example 3: Adding a form action without redefining form

Similarly to example 2, you can patch the existing toolbar for forms:

Trestle.resource(:missiles) do
   # ...
  controller do
    def show
      toolbar(:primary) do |t|
        t.link("Launch", instance, action: :trigger, method: :post, icon: "fa fa-check")
      end
    end

    def trigger
      id = params[:id]
      LaunchMissileJob.perform_later(missile_id: id)
      flash[:message] = "Missile will be launched soon"
      redirect_back fallback_location: admin.path(:show, id: id)
    end
  end

  routes do
    post :trigger, on: :member
  end
end