Bazley
Bazley

Reputation: 2847

Rails routes.rb not working as desired with named routes

I have this code to link to a new persona:

<%= link_to "New Persona", genesis_path, class: "new-persona-button" %>

My routes.rb file:

Bazleyapp::Application.routes.draw do

  resources :users,    only: [:index, :create]
  resources :personas, only: [:index, :create]

  root                       'static_pages#home'

  get     'signup',                 to:  'users#new'
  get     '/:callsign',             to:  'users#show',     as: :user
  get     '/:callsign/settings',    to:  'users#edit',     as: :edit_user
  patch   '/:callsign',             to:  'users#update',   as: :update_user
  delete  '/:callsign/terminated',  to:  'users#destroy',  as: :destroy_user

  get     'genesis',                to:  'personas#new'
  get     '/:callsign',             to:  'personas#show',     as: :persona
  get     '/:callsign/settings',    to:  'personas#edit',     as: :edit_persona
  patch   '/:callsign',             to:  'personas#update',   as: :update_persona
  delete  '/:callsign/terminated',  to:  'personas#destroy',  as: :destroy_persona

end

Clicking on the new persona button produces this error:

Started GET "/genesis" for ::1 at 2014-12-03 00:25:38 +0000
Processing by UsersController#show as HTML
Parameters: {"callsign"=>"genesis"}
User Load (0.4ms)  SELECT  "users".* FROM "users" WHERE "users"."callsign" = $1 LIMIT 1  [["callsign", "bazzer"]]
User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."callsign" = $1 LIMIT 1  [["callsign", "genesis"]]
Completed 500 Internal Server Error in 21ms

NoMethodError (undefined method `activated' for nil:NilClass):
app/controllers/users_controller.rb:17:in `show'

Which means it's hitting the user_path (users#show) when it should be hitting the genesis_path. But I've told it to hit the genesis path with <%= link_to "New Persona", genesis_path, class: "new-persona-button" %>. Am baffled. Where is the error?

Upvotes: 1

Views: 67

Answers (2)

Ken Stipek
Ken Stipek

Reputation: 1522

I don't think what you have here is going to work as you are overwriting several routes. You may want to consider putting these in separate namespaces so they are unique.

Example:

Bazleyapp::Application.routes.draw do

  resources :users,    only: [:index, :create]
  resources :personas, only: [:index, :create]

  root                       'static_pages#home'

  namespace :users do
    get     'signup',                 to:  'users#new'
    get     '/:callsign',             to:  'users#show',     as: :user
    get     '/:callsign/settings',    to:  'users#edit',     as: :edit_user
    patch   '/:callsign',             to:  'users#update',   as: :update_user
    delete  '/:callsign/terminated',  to:  'users#destroy',  as: :destroy_user
  end

  namespace :personas do
    get     'genesis',                to:  'personas#new'
    get     '/:callsign',             to:  'personas#show',     as: :persona
    get     '/:callsign/settings',    to:  'personas#edit',     as: :edit_persona
    patch   '/:callsign',             to:  'personas#update',   as: :update_persona
    delete  '/:callsign/terminated',  to:  'personas#destroy',  as: :destroy_persona
  end
end

That way you separate paths for these routes.

You can also add a block to the resource and not have to split it up. Example:

resources :users,    only: [:index, :create] do
  get     'signup',                 to:  'users#new'
  get     '/:callsign',             to:  'users#show',     as: :user
  get     '/:callsign/settings',    to:  'users#edit',     as: :edit_user
  patch   '/:callsign',             to:  'users#update',   as: :update_user
  delete  '/:callsign/terminated',  to:  'users#destroy',  as: :destroy_user
end

Upvotes: 1

emaxi
emaxi

Reputation: 1809

Put

get 'genesis', to: 'personas#new'

before

get '/:callsign', to: 'users#show', as: :user

You have to know that the routes file is read from top to bottom.

Upvotes: 1

Related Questions