Search code examples
ruby-on-railsnested-attributes

Button for updating attribute of nested resource


I am trying to update an attribute of a nested resource using a button but cannot get it to work. Requests are a nested resource of Gigs. A user can see a list of all the requests for his particular gig, with a button after each for 'hire' and 'reject'.

The closest I have come is with;

<%= form_for ([@gig, @gig.requests.build]) do |h| %>
  <%= h.hidden_field :status, value: "hired" %>
  <%= h.submit "Hire", class: "btn" %>
<% end %>

As I have .build it duplicates the 'request' with the correct status but leaves the original untouched. I have tried using .update and .patch but these don't work, and as I can't find a list of variables, any further attempts would be useless.

I have also tried the link_to method eg.

link_to("Hire", gig_requests_path(@request, :status => "hired"), :method => :put, :confirm => "Are you sure?")

which gives a no route error.

I seem to have got closest with the form method although I imagine the link method isn't working as I am probably messing up due to the resource being nested. Any clarification would be greatly appreciated!

Just in case:

def update
    @request = Request.find(params[:id])
      if @request.update(request_params)
      redirect_to gig_path(@gig)
    else
      render 'edit'
  end
end

private

def request_params
  params.require(:request).permit(:message, :gig_id, :status)
end

Routes:

resources :gigs do
      resources :requests
end

Solution

  • In the end I did it as so:

    routes:

    resources :requests
          post 'request/:id/hired' => 'requests#hired', as: :hired_request
          get 'hired'
    

    controller:

    def hired
      @request = Request.find(params[:id])
          @request.update(status: "hired")
          @request.save
          redirect_to gig_requests_path
          flash[:notice] = "MARKED AS HIRED"
    end
    

    and the view:

    <td>
    <%= button_to "Hire user", { action: "hired", id: request.id },
                                    method: :post, data: { confirm: "Are you sure?" } %>
    </td>