Using Rails link_to for links that post
Asked Answered
D

6

107

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.

Daloris answered 16/11, 2012 at 10:24 Comment(2)
don't think you can do that. probably best doing it in your controller with net/http or HTTParty?Madrepore
Can't do it in my controller, user needs to be directed to the other site. Looks like you're right though, there isn't a built-in link mechanism to do this for me.Daloris
A
167

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
Anarthria answered 16/11, 2012 at 10:32 Comment(3)
Just updated my question, I'm actually using an external URL for these links.Daloris
I've added a note basically saying that what you want to do is not possible using a link. You need a form with a submit button.Anarthria
It's important to note that if a user has javascript disabled the link will default to a "GET" request.Nakashima
B
16

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.

Beltz answered 16/2, 2017 at 15:9 Comment(1)
Agreed with Kostas. Moreover, link_to with method post doesn't work well on Internet Explorer.Duncan
F
10

For Rails 7 with Turbo

link_to "Profile", profile_path(@profile), data: { turbo_method: "post" }
Felicidad answered 7/7, 2022 at 9:34 Comment(0)
N
8

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.

Nata answered 16/11, 2012 at 10:56 Comment(5)
This is indeed a very nice way to add the parameters.Lustig
Doesn't work for my needs, the parameters need to be POST parameters. But thanks, I didn't know about the to_param method. You also need a ? after profile.Daloris
Ok I understand, then I think you have to write a form. You can write an helper method which will build this form if you need to repeat this logic several times.Nata
Notwithstanding that this doesn't answer the OP's question, you should use a url helper for this as in @shioyama's answerLaudanum
@BenWest : the helper was not initially used and I assumed it was meaningful (it may have been an external URL for example)Nata
F
1

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')

Flattie answered 13/9, 2014 at 5:31 Comment(0)
P
1

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} %>
Plumb answered 29/8, 2015 at 8:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.