Reputation: 873
I'm trying to create a cancel button in a rails view, which links to a PATCH/update method. I want to pass a query string parameter -- update_action: "cancel" -- so the update method knows that this is a cancel action and can process it accordingly. This is the link_to method for the cancel button:
<%= link_to "Cancel", {controller: "/orders", action: "update", id: order.id, update_action: "cancel" }, method: "patch" %>
However, when I do this, I get a routing error:
Unable to find route for [GET] order/update/id?update_action=cancel
For some reason it is trying to route to a GET request instead of a PATCH request.
Now, when I remove the query string parameter from the link_to method, i.e.
<%= link_to "Cancel", {controller: "/orders", action: "update", id: order.id }, method: "patch" %>
It correctly routes to PATCH orders/id,
Why is my link_to method not routing to a PATCH request when I include the query string parameter?
Note, by routes.rb file contains:
resources :orders
Upvotes: 3
Views: 2734
Reputation: 779
You can give this a try, though I doubt it will work any better:
<%= link_to "Cancel", order_path(id: order.id, update_action: "cancel"), method: "patch" %>
Routing in rails is implemented using RESTful architecture. Hence you can send query string params with a GET request. A PUT request typically does not contain query params. Those params are submitted in the request body (like using a form) as seen in the example below from guides
class ClientsController < ApplicationController
# This action uses query string parameters because it gets run
# by an HTTP GET request, but this does not make any difference
# to the way in which the parameters are accessed. The URL for
# this action would look like this in order to list activated
# clients: /clients?status=activated
def index
if params[:status] == "activated"
@clients = Client.activated
else
@clients = Client.inactivated
end
end
# This action uses POST parameters. They are most likely coming
# from an HTML form which the user has submitted. The URL for
# this RESTful request will be "/clients", and the data will be
# sent as part of the request body.
def create
@client = Client.new(params[:client])
if @client.save
redirect_to @client
else
# This line overrides the default rendering behavior, which
# would have been to render the "create" view.
render "new"
end
end
end
If you only want a 'Cancel' button, you can use the same path as a GET request. Your params {update_action:"cancel"} will be available in the controller. It also makes sense as you are trying to GET/fetch a different page.
A PUT/PATCH request is used to update/create data in models, while POST is to create. A GET request will fetch pages, or back to previous pages (like in cases of 'cancel').
Upvotes: 1