Photo by Juliana Barquero on Unsplash
undefined local variable or method `root_path' for #<XXXController> in Rails
TL; DR: If you specify a new name for a route, a new path is also going to be defined.
Problem
Rails doesn't not redirect to root_path
, even though there's a root route defined in the routes.rb
file.
Error
Let's check the error in several different angles.
Full message
undefined local variable or method `root_path' for #<XXXController:0x00007f4704ba2f50> Did you mean? XXX_path
Snapshot
Code
if @cart.id != session[:cart_id]
redirect_to root_path, alert: "Access denied."
end
The previous piece of code is inside a method called set_cart
. When the method is invoked, Rails raises that error.
Explanation
This error message typically occurs when the root_path helper method is not recognized within a specific controller context.
The error suggests that the root_path
helper is being called within the XXXController, where XXX represents the name of the controller, but it is not defined or accessible in that context.
Solution
1- Make sure you invoked the root_path
correctly. No typos.
This snippet shows a good use of the root_path
helper. Make sure you're using it correctly.
if @cart.id != session[:cart_id]
redirect_to root_path, alert: "Access denied."
end
2- Check your routes list
You can accomplish this step by using two possible approaches: the terminal or the browser.
The idea is to display the application's defined routes. This step is going to provide a list of all routes defined in the config/routes.rb
file along with their corresponding HTTP verbs, URL patterns, controller actions, and route names.
Browser
In your browser, type the following:
http://localhost:3000/routes
Your browser is going to render a single view page with all routes.
Terminal
First, make sure you are in the root directory of your application in the command line. Running this command will display the list of routes configured in your application.
In Rails 4 and earlier versions, rake routes
is the default command. Let's check it out.
bundle exec rake routes
Starting from Rails 5, the best command is the following:
rails routes
In Rails 6, it's possible to use the --expanded
argument. This argument formats the routes in the screen.
rails routes --expanded
The result would look something like this
it's possible to filter by using grep
3- Make sure you have a root route defined
In your routes.rb
file, which is located inside the config
directory, make sure you have a root route added there.
The following code is the correct form of the root route
# config/routes.rb
Rails.application.routes.draw do
resources :line_items
resources :carts
root 'store#index'
resources :products
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
In the previous example, the root path is going to invoke the action index of the controller store.
however, based on my real case scenario, take a look at my config/routes.rb
file.
# config/routes.rb
Rails.application.routes.draw do
resources :line_items
resources :carts
root 'store#index', as: 'store_index'
resources :products
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
Yes, the root route is defined, but I'm using a named route:
# config/routes.rb
[...]
root 'store#index', as: 'store_index'
[...]
4- Pay attention with named routes
Basically, named routes
are a way to give a specific name to a route defined in the application's routing configuration.
When a named route is used, a new path is created based on it.
Look at the following code again, since I used a named route for the root, my path was changed to store_index_path
.
# config/routes.rb
Rails.application.routes.draw do
resources :line_items
resources :carts
root 'store#index', as: 'store_index'
resources :products
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end
In order to solve the root_path
error, I need to remove my named route:
# config/routes.rb
[...]
root 'store#index'
[...]
Another option is to forget this root_path
error and use the new generated path, which is store_index_path
# config/routes.rb
[...]
root 'store#index', as: 'store_index'
[...]
5- Test it
You can test it by checking your routes list again. If you decide to remove your named route, you should be able to see your root_path
again.
# config/routes.rb
[...]
root 'store#index'
[...]
Let's connect
Final thoughts
I hope this article helped you. Let me know if you have any questions.
Your thoughts, suggestions and corrections are more than welcome.
By the way, feel free to drop your suggestions on new blog articles.
Hope to see you next time.