How does article_path work? (RubyOnRails Tutorial)

I follow the official ruby ​​in the rail guide and I just finished chapter 5.9.

Adding links should be easy, but I'm very 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 use this, I have a view:

<h1>New Article</h1>

<%= form_for :article, url: articles_path do |f| %>
    <%= f.label :title %><br>
    <%= f.text_field :title %>

    <%= f.label :text %><br>
    <%= f.text_area :text %>

    <%= f.submit %>
<% end %>

<%= link_to 'Back', articles_path %>


This view has a submit form and a link at the end. According to ruby, I am specifying a submit button link on a form using articles_path

in <%= form_for :article, url: articles_path do |f| %>


I don't really know how this variable is set, but I'll take the bait and accept it. According to the manual, when you click the submit button articles_path

, "POST / articles (.: Format) articles # create" will be generated by default.

However, in the link <%= link_to 'Back', articles_path %>

, articles_path

it is supposed to redirect us to the index page ...

Can someone explain to me how the same variable has 2 radically different behaviors in the same view?


source to share

3 answers

How action view methods work:


The default request type is 'GET'.


The default request type is "POST".

Each generated route is of a specific type, i.e. how the rails map different requests to the correct ones.

For form_for

the action helper method, it distinguishes between "POST" and "PUT" automatically depending on whether you submitted an instance or not in the form.

you can also explicitly specify the method type for the form by adding

method: 'GET' OR :html => { :method => 'GET' }


** check out different syntax possibilities depending on rails version.

The same goes for other methods, so if you want to link_to

post a post request, you need to pass method="POST"


** How rails distinguish between indexes and show actions **

In the generated routes table, you may have noticed that the index action does NOT need an instance id as it should list all entries. However, for showing you need to pass an instance to it as it should only show the specific instance.

= link_to "index", articles_path
= link_to "show", article_path(article)



The two methods are not the same thing, "articles" and "article", plural and singular. Even if they were identical in name, one of them will accept the instance and the other will not.



The better you can understand when you look at the HTML output it generates.

<%= form_for :article, url: articles_path do |f| %>

generates HTML output as shown below

<form accept-charset="UTF-8" action="/articles/create" method="post">


So the form is sent 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 look like below

<a href="/artcles">Back</a>


to make it jump to the page as it matches url type and...



There is a bit of magic, the form designer knows the http method will be POST and the url will be / articles. Same as when you develop an edit action, then the form builder will know that the action will be PATH / PUT and the url will be / articles / 1, because you will need to pass an article instance to create the helper.

The same magic is the link_to helper, it knows that by default it is the GET http method unless you specified exactly.



All Articles