Reputation: 17574
I am following the official ruby on rails tutorial and I just finished chapter 5.9.
Adding links should be simple but I am majorly confused.
When I type bin/rake routes
, I get the following output:
fl4m3ph03n1x: ~/blog $ bin/rake routes
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
root GET / welcome#index
fl4m3ph03n1x: ~/blog $
Which makes sense according to the tutorial.
To make use of this, I have a view:
<h1>New Article</h1>
<%= form_for :article, url: articles_path do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
<%= link_to 'Back', articles_path %>
This view has a submit form and a link in the end.
According to ruby, I specify the submit button link in the form by using articles_path
in <%= form_for :article, url: articles_path do |f| %>
.
I really have no idea how that variable is set, but I will take the bait and accept it.
According to the tutorial, when clicking the submit button articles_path
will be "POST /articles(.:format) articles#create" by default.
However, in the link <%= link_to 'Back', articles_path %>
, articles_path
is supposed to redirect us to the index page...
Can someone explain me how the same variable has 2 radically different behaviors in the same View ??
Upvotes: 4
Views: 2287
Reputation: 4744
link_to
default request type is 'GET'.
button_to
default request type is 'POST'.
Each generated route has a specific type, which is how rails map different requests to the correct ones.
For form_for
action view helper method, it differentiates between 'POST' and 'PUT' automatically depending on whether you passed an instance or not to the form.
you can also explicitly provide the method type for the form by adding
method: 'GET' OR :html => { :method => 'GET' }
** check different syntax capabilities depending on rails version.
Same goes to other methods, so if you want link_to
to send post request you have to pass method="POST"
to it.
In the generated routes table you may have noticed that index action does NOT need an instance id because it is supposed to list all articles. However, for show, you need to pass an instance to it, because it is supposed to show a specific instance only.
= link_to "index", articles_path
= link_to "show", article_path(article)
NOTICE ::
The two methods is not the same, "articles" and "article", plural vs singular. Even if they were identical in names one of them will take an instance and the other won't.
Upvotes: 5
Reputation: 33542
The better you can understand when you look into the HTML output it generates.
<%= form_for :article, url: articles_path do |f| %>
generates the HTML output something like below
<form accept-charset="UTF-8" action="/articles/create" method="post">
So the form submits to the create action with a POST request.
When it comes to link_to
, the default request type is GET.
The HTML output generated for <%= link_to 'Back', articles_path %>
will be something like below
<a href="/artcles">Back</a>
so the it takes you to the index page as it matches the url and request type.
Upvotes: 2
Reputation: 1665
There is bit magic behind, form builder know that method http method will be POST and url will be /articles. Same as when you will be developing edit action then form builder will know that action will PATH/PUT and url will be /articles/1 because you will have to pass instance of article to form helper.
Same magic is link_to helper he knows that default is GET http method unless you exactly specify.
Upvotes: 0