Projjol
Projjol

Reputation: 1375

Understanding 'GET' routes in rails

In my routes file I have specified:

resources :cards do
end

Apart from the basic CRUD routes I have another route which is as follows:

get '/cards/get_schema' => 'cards#get_schema'

When I hit this endpoint, I'm actually taken to cards#show. Why does this happen?

Upvotes: 0

Views: 35

Answers (3)

AnkitG
AnkitG

Reputation: 6568

It depends on the order of routes defined.

Order 1

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  resources :cards do
  end

  get '/cards/get_schema' => 'cards#get_schema'
end

Running routes

rake routes

Output

~/D/p/p/s/console_test> rake routes
          Prefix Verb   URI Pattern                 Controller#Action
           cards GET    /cards(.:format)            cards#index
                 POST   /cards(.:format)            cards#create
        new_card GET    /cards/new(.:format)        cards#new
       edit_card GET    /cards/:id/edit(.:format)   cards#edit
            card GET    /cards/:id(.:format)        cards#show #<======== 
                 PATCH  /cards/:id(.:format)        cards#update
                 PUT    /cards/:id(.:format)        cards#update
                 DELETE /cards/:id(.:format)        cards#destroy
cards_get_schema GET    /cards/get_schema(.:format) cards#get_schema #<========

Since show expects cards/:id and is above /cards/get_schema it gets routed to cards#show

Order 2

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  get '/cards/get_schema' => 'cards#get_schema'

  resources :cards do
  end

end

Running routes

rake routes

Output

  ~/D/p/p/s/console_test> rake routes
          Prefix Verb   URI Pattern                 Controller#Action
cards_get_schema GET    /cards/get_schema(.:format) cards#get_schema #<========
           cards GET    /cards(.:format)            cards#index
                 POST   /cards(.:format)            cards#create
        new_card GET    /cards/new(.:format)        cards#new
       edit_card GET    /cards/:id/edit(.:format)   cards#edit
            card GET    /cards/:id(.:format)        cards#show #<========
                 PATCH  /cards/:id(.:format)        cards#update
                 PUT    /cards/:id(.:format)        cards#update
                 DELETE /cards/:id(.:format)        cards#destroy

In this scenario /cards/get_schema will be top level and won't conflict with cards#show

Upvotes: 1

hoffm
hoffm

Reputation: 2436

Rails is treating get_schema as the id of a card. The solution is to reorder the route declarations, like so:

get '/cards/get_schema' => 'cards#get_schema'

resources :cards do
end

This way the get_schema route will be matched before the show route.

Upvotes: 1

Ursus
Ursus

Reputation: 30056

One route generated by resources :cards is get '/cards/:id'. Can you see the issue? get_schema is recognized as id. Try this one

resources :cards do
  get 'get_schema', on: :collection
end

Or just put that route on top

get '/cards/get_schema' => 'cards#get_schema'
resources :cards

Upvotes: 1

Related Questions