Portabello
Portabello

Reputation: 65

Ruby on Rails: link_to vs button_to

I am having trouble implementing the method link_to. My program uses a link to call a controller method which performs some logic and renders a partial. The issue is I cant get the link to call the controller method. I have tried calling the same controller method with button_to and it seems to work. Looking at the API of both ActionView helper methods button_to and link_to it seems like the parameters should be the same. However, the following two lines of code do two different things.

_product.html.erb

<%= link_to 'view individual', products_view_individual_product_page_path(product_id: product.id)%>
<%= button_to 'view individual', products_view_individual_product_page_path(product_id: product.id)%>

The link_to call will cause an error ActiveRecord::RecordNotFound error stating "Couldn't find Product with 'id'=view_individual_product_page" and the passed parameters are {"product_id"=>"261", "id"=>"view_individual_product_page"}, im not sure why it is trying to pass the path of my controller method as the id. However the button_to line of code works just fine, and I am in the specified controller method. Here is the route entry in my routes.rb file...

routes.rb

post 'products/view_individual_product_page'

Can anyone explain to me what I am doing wrong here, I cant find much information online about why the path is being passed as an ID in link_to but not button_to

Upvotes: 1

Views: 2343

Answers (2)

arieljuod
arieljuod

Reputation: 15838

Add method: :post as an option for link_to.

link_to 'view individual', products_view_individual_product_page_path(product_id: product.id), method: :post

"A" tags always does GET requests and you are expecting a POST request. Note that you need Rails Unobtrusive Javascript for links to trigger a POST request with Rails doing some magic behind the scenes (check your javascript application.js, you should have a require rails-ujs).

Usually, if you need to do a POST request it's okey to have a button_to since it actually renders a FORM tag with a button to do a proper POST request without the need of Rails UJS.

Check the doc for both: https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/UrlHelper.html#method-i-button_to https://api.rubyonrails.org/v5.2.3/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to

Upvotes: 5

Ursus
Ursus

Reputation: 30056

I think the difference is that link_to by default use a GET method, where button_to use POST. So if you want a different method, specify it

<%= link_to 'view individual', products_view_individual_product_page_path(product_id: product.id), method: :post %>

Upvotes: 1

Related Questions