Carpetfizz
Carpetfizz

Reputation: 9169

Understanding the "do, end" syntax in routes.rb

Regarding the following bit of code:

Rails.application.routes.draw do
  get 'welcome/index'

  resources :articles do
    resources :comments
  end

  root 'welcome#index'
end

To my understanding, Rails.application.routes.draw is a method that accepts a block, and what's defined between the do end is the said block?

Upvotes: 2

Views: 1477

Answers (4)

Vasanth Saminathan
Vasanth Saminathan

Reputation: 585

If you open and see the draw method implementation at /.rvm/gems/ruby-2.4.7@itildesk/gems/actionpack-4.2.11.1/lib/action_dispatch/routing/route_set.rb:408 you would get a better clarity.

It accepts a block of code. i.e. whatever is in between do and end and executes instance_exec, which in turn going to add all the resources or paths you mentioned to a variable of their routes internal.

Whenever you encounter do-end block, just have a mind map that the code block is being passed as a parameter, which will be executing somewhere.

Upvotes: 0

IDIR GACI
IDIR GACI

Reputation: 54

The ressources key word represent the crud RESTFULL functions (create, read, update, destroy) so when we put

resources articles ==> create the crud routes for article model and for every article we have comments so if we want to create a new comment for article we have to precise the article resource.

for example to create a new comment for article with 1 Id

blablabla.com/articles/1/comment/new

and if we want to destroy the comment with id 144 of article with Id 1

blablabla.com/articles/1/comment/144 on DELETE http request

Upvotes: 0

akuhn
akuhn

Reputation: 27803

Yes, resources is a function that takes a block.

Internally the block is executed within the scope of the parent resource, the code for that looks like this (simplified)

def resources(resource, &block)
   ...
   begin
     # make resource the new parent before calling the block
     @scope.push(resource)
     # call the block
     yield
   ensure
     # restore the previous parent
     @scope.pop
   end
   ...
end

Like this the nesting of the resources and the nesting of your code in the routes.rb file are mirroring each other.

See here for the full code, https://github.com/rails/rails/tree.master/actionpack/lib/action_dispatch/routing/mapper.rb

Upvotes: 1

Omid Kamangar
Omid Kamangar

Reputation: 5788

You can write a block in Ruby in two ways:

In the short version code is surrounded by { and }. This version is mostly used for one line of code.

names.each { |name| puts name }

In the long version code is surrounded by do and end. This is the multiline version. The code sample you posted is a good example of a multiline block.

Rails.application.routes.draw do
  get 'welcome/index'

  resources :articles do
    resources :comments
  end

  root 'welcome#index'
end

Upvotes: 6

Related Questions