1

I'm looking at this tutorial: https://www.railstutorial.org/book/sign_up

We get on to rails resources.

config/routes.rb

Rails.application.routes.draw do
  root             'static_pages#home'
  get 'help'    => 'static_pages#help'
  get 'about'   => 'static_pages#about'
  get 'contact' => 'static_pages#contact'
  get 'signup'  => 'users#new'
  resources :users
end

app/controllers/users_controller.rb

class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
  end

  def new
  end
end

app/views/users/show.html.erb

<%= @user.name %>, <%= @user.email %>

There is also this handy table of telling us how ruby will handle the various requests to the Users resource.

enter image description here

I have two questions here.

  1. How does RoR know when accessing the /users, /users/1 etc urls, what to actually use the index, show methods.

  2. More importantly, - when the show method is called, how it does it know the give the show.html.erb view to browser? What if I wanted to return a different view?

dwjohnston
  • 11,163
  • 32
  • 99
  • 194

3 Answers3

3

1. Rails knows which methods to use based on the HTTP request type (GET, POST, PUT, or DELETE) and the endpoint. So when you hit the '/users' endpoint with a GET request, it will use the index method. When you hit the '/users/:id' endpoint with a GET request, it will use the show method.

2. The show.html.erb view is used because the name matches the show method. To use a different view, just use match in the routes file like so:

match "users" => "users#show"

The example above would match the '/users' route to the '/user/:id' route.

Alex Pan
  • 4,341
  • 8
  • 34
  • 45
  • 1
    Just wanted to add that `match` means that all HTTP verbs will hit it equally, so in this case even a POST would go to UsersController#show. If you need different functionality Rails also has `get` `post`, etc. that you can use instead of `match` (or if you want a few to match but not all you can use `match "users" => "users#show", via: [:get, :post]` [More info](http://api.rubyonrails.org/classes/ActionDispatch/Routing.html) – Mario May 10 '15 at 03:58
  • What's say you wanted to dynamically assign the route depending on the kind of user it was? – dwjohnston May 10 '15 at 04:16
  • @dwjohnston You should see [this question](http://stackoverflow.com/questions/11230130/rails-routes-based-on-condition). The users first go to a home route which has a case statement and depending on the user type, the application will render a specific view. – Alex Pan May 10 '15 at 04:42
  • @Mario yes you are correct. Thank you for the additional info! – Alex Pan May 10 '15 at 04:42
1

The mechanism that is responsible for dispatching actions in response to requests is router. You define all the routes in config/routes.rb file as you said. Each line in this files define the request in clear way. resources is a shorthand to define a set of routes - all of them listed here.

There are two thins that distinct requests - the URL and the HTTP request type (GET, POST, PUT, DELETE). Based on these two things you can clearly direct the request to proper controller. Take a look on this one:

get 'help' => 'static_pages#help'

This means: If you get a request of type get directed to url of value /help dispatch the request to controller static_pages and its action help. What happens in help action is a matter of code.

This is also an answer to your second question, how does Rails know what template should it render. Assume that we still work on above example of help action. If this action has no explicit render call, Rails will use its convention over configuration and search for a template that will be in directory called as the controller and in file name as the action name. Therefore, it will render the file that is in app/views/static_pages/help.html.erb. On the other hand, the developer can call render with explicit other file name, e.g.: render "products/show".

If you want to find more please take a look at these two Rails guides:

Kuba Niechciał
  • 974
  • 7
  • 9
0

rails is said to have convention over configuaration. this is one of the strongest feature available in Rails.in another way. Smart and less code. Here when u say method name as show. rails by default will look for show.html.erb. if you want to explicitly render some other view. You can do this in your controller methods

render :new_view_name

Regarding the routes.

resources :users

This is very helpful when we have Rest calls ,crud operations.it creates 7 urls for crud. And how it differentiate is depending on http data type.

Hemali
  • 465
  • 4
  • 8