Using Rails link_to for links that post

2019-01-13 12:13发布

问题:

I have a link that I need to submit a post request with. Normally, I'd use jQuery and prevent the link's default behavior and then submit a form to the destination. This seems like something Rails should be able to help me out with. Sure enough, the link_to method has an option for specifying a POST http method:

link_to "Profile", 'http://example.com/profile', method: :post

That works, but I need to add 2 parameters too. I tried:

link_to "Profile", 'http://example.com/profile', method: post, param1: 'value1', param2: 'value2'

That just added those parameters to the <a> HTML element, but didn't submit those when clicking the link:

<a rel="nofollow" param1="value1" param2="value2" data-method="post" href="http://example.com/profile">Profile</a>

Is there a way to do a POST request with parameters using link_to or any other Rails method? I'm using Rails 3.2.9.

回答1:

The short answer is that if what you mean by "parameters" is form fields, then you simply can't do this (at least not in a straightforward way that I can see). You should instead use a form with a submit button, styled to look like a link (if that's what you want it to look like).

If on the other hand you had meant query parameters, then this would work:

link_to "Profile", profile_path(@profile.id, param1: 'value1', param2: 'value2'), method: :post


回答2:

You can encode parameters in the URL this way :

link_to "Profile", 'http://example.com/profile?' + {param1: 'value1', param2: 'value2'}.to_param, method: :post

If it does not fit your needs you are better use a form than a link_to.



回答3:

The parameters and the http method should be together {param1: 'value1', param2: 'value2', :method: :post}

<%= link_to "Profile", profile_path(@profile), {param1: 'value1', param2: 'value2', method: :post} %>


回答4:

In order to POST data, you need a form. However, you don't need a submit button. If you want this to look like a link for some reason, you can actually make it a link that submits the form via JavaScript. In the example below, the POST resource is just a REST action that does not require any fields so there are no form input controls. If you wanted to post some data, just put hidden input fields in the form.

<%= form_tag('http://something_postable', :method => :post, :class => 'internal') %></form>
<%= link_to_function('Label for Link', 'previous("form").submit()', :title => 'Hover text for link') %>

The form is assigned a class so you can style it or hide it via CSS (e.g. 'display: inline')



回答5:

Note that if the user has JS disabled or you have removed the unobtrusive JS libraries that come by default, link_to will be silently submitted via a GET request.

In general, I am not very fond of having links that perform POST requests. I think that's the role of a form and a button.

Thus, an easy (and safer) alternative is to use the Rails button_to helper:

button_to 'Profile', profile_path(@profile, param1: 'value1', param2: 'value2')

button_to also supports the method option but as it defaults to post so I've just omitted it.