Namespaced Rails 'root to:' route not working as expected - ruby-on-rails

I'm reading the Rails Guides on routes (Routes From The Outside In), and I saw the following:
You can also use root inside namespaces and scopes as well. For
example:
namespace :admin do
root to: "admin#index"
end
root to: "home#index"
I'm trying to replicate this to see how it works, so in my config/routes.rb file I've got the following code:
namespace :admin do
root to: 'users#index'
end
I expected to be able to visit 'localhost:3000/admin' and be directed to the users#index page, but instead I got the error message 'uninitialized constant Admin'.
Am I misunderstanding what the example code is supposed to do, or is there something wrong with what I wrote?

namespace :admin, would route you to the controller Admin::UsersConroller. If you want to route /admin to UsersConroller, you should use scope instead of namespace.
scope '/admin' do
root to: 'users#index'
end
You can read more about it here

Related

How to use multiple root route in rails 6?

Just updated to rails 6 and having trouble with a conditional root route
devise_scope :user do
authenticated do
root to: 'users#show'
end
unauthenticated do
root to: 'visitors#index'
end
end
I've attempted to check for the logged-in user in visitors#index and do a redirect to users#show but now I have this ugly URL '/users/:id' instead of being able to visit users#show with a clean root URL.
In my case I was able to solve this by adding an :as argument:
devise_scope :user do
authenticated do
root to: 'users#show'
end
unauthenticated do
root to: 'visitors#index', as: :visitors_url
end
end
I think the reasoning behind the change is to make it so that Rails knows where to route root_url.
Note: I found the answer on reddit where it was suggested using namespace would be cleaner.
namespace :visitors, path: nil do
root to: 'visitors#index'
end
I don't know if there is a way to make that work with devise though.

Ruby on Rails Separate admin folder, controllers and layouts

I am new to Ruby on Rails. I want to have following structure for admin section.
app/controller/admin/admin_controller.rb and all other admin section controller under app/controller/admin/ folder
app/views/layout/admin/admin.html.erb to keep separate html layout for admin section
At the same time i want to use Devise Gem for admin and front end user authentication.
I executed rails g devise:views admin, rails generate devise Admin and rails g controller admin/home index command that created views, model and controller for admin user. Now what routes and other setting i need to add so that ruby could understand that if i type http://localhost:3000/admin/ then i should be redirected to http://localhost:3000/admins/sign_in/ page and after entering correct admin credentials i should redirected to index method of controllers/admin/home_controller.rb
is it also possible to keep singular convention of Devise admin views like admin/sign_in instead of admins/sign_in ?
I have searched a lot but could not get relevant help. Please provide steps to achieve above.
Thanks in advance.
This is how route file looks like
Rails.application.routes.draw do
namespace :admin do
get 'home/index'
end
devise_for :admins
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root to: "home#index"
end
When i type http://localhost:3000/admin/ then i get below error
Your problem is that you do not have root route defined for /admin.
I have the same URL convention routes in one of the apps and routes.rb looks like this:
Rails.application.routes.draw do
# Admin part
devise_for :admins, path: '/admin'
scope module: :admin, path: '/admin', as: 'admin' do
root to: 'home#index'
end
# Redirect app root to client part
root to: redirect(path: '/panel', status: 301)
# Client part
devise_for :clients, path: '/panel'
scope module: :panel, path: '/panel', as: 'panel' do
...
end
end

Map routes into other routes in Rails

I'm having some troubles with routes in Ruby on Rails v5.2.0
Currently, I have a resource called users, so that I have a controller which takes actions (for example index) whenever I start my server in localhost on port 3000 and type in my browser
localhost:3000/users/
Is there an easy way to map the requests for this resource to the app root?Basically, I'm trying to achieve this:
localhost:3000/users/ --> localhost:3000/
localhost:3000/users/new/ --> localhost:3000/new/
This is how my routes.rb file looks like right now:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users
root to: 'landing#index'
end
Add the following lines to your routes.rb file
Change
root to: 'landing#index'
to
root "users#index"`
and add the line
get "/new" => "users#new"
Also if you want to learn more on routing, here is the link
http://guides.rubyonrails.org/routing.html
TLDR - Rails doesn't have a root model generator for routing
You can manually create the individuals routes
get :new, to: "users#new", as: "new_user"
...
However while using the rails generators resources you are just specifying a shorthand for
scope :model do
get :new, to: "model#new", as: "new_model"
...
end
You can checkout the rails guide to routing for more specifics on explicit creation
http://guides.rubyonrails.org/routing.html
HACKY SOLUTION
root to: "users#index", as: "users"
get :new, to: "users#new", as: "new_user"
post "/", to: "users#create"
scope ":id" do
root to: "users#show"
get :edit, to: "users#edit", as: "edit_user"
patch "/", to: "users#update"
...
end
It looks that what you want is to 'mute' users from the url. An option for this is to call path: '' on users like this:
Rails.application.routes.draw do
devise_for :users
get 'landing/index'
get 'welcome/index'
resources :users, path: '' # <-- HERE
root to: 'landing#index'
end
The value you give to path: is going to replace the resource name.
In this scenario users is being replaced with an empty string '', but it could be any other string.
This will remove users. However, you must consider that root to: 'landing#index AND users#index are both pointing to localhost:3000/
Without knowing your app, an option to solve this scenario, could be to have landing#index as root for gustes (not authenticated users) and users#index as a root for authenticated users.

Sometimes getting an "Invalid Route Name" Error in Rails

I am getting the following error only on occasion when I attempt to load up my Rails app in localhost.
Invalid route name, already in use: 'root' You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with resources as explained here: http://guides.rubyonrails.org/routing.html#restricting-the-routes-created
For some reason, it only happens every now and again, and generally goes away after I refresh the page once. The file it is calling into question has this as the code (line causing the error indicated):
Rails.application.routes.draw do
get 'welcome/index'
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
Rails.application.routes do
resources :articles
root 'welcome#index' #-->This is the line that causes the error
end
resources :articles do
resources :comments
end
end
I am really new to Rails, and I'm not sure what is causing the problem or if would even be a problem if I were to actually host this beginner project on the web. Also, if it helps, I am running Ruby 2.2.2 and Rails 4.2.1.
Thank you in advance for the help!
You have (Rails.application.routes) nested inside (Rails.application.routes.draw). Run rake routes and you will see that you have resources for articles twice. Furthermore, you have root 'welcome#index' nested inside and that is why you are getting the error. Your routes should look like this
Rails.application.routes.draw do
get 'welcome/index' => 'welcome#index'
root 'welcome#index'
resources :articles do
resources :comments
end
end
Note that the route of your application meaning(/) and (/welcome/index) both point to the welcome controller index action. You don't really need get 'welcome/index' => 'welcome#index' and you can delete that line and use root when ever you need the index action from the welcome controller.
Try using the "Full" syntax.
root :to=> "some#action"
You have two routes pointing to the same page index, get rid of your get route
get 'welcome/index'
Also your root route is nested that should be moved outside since the root route is the root of your entire app and not a specific resource

Default resource for namespaced route?

With routing in Rails 3, using a namespaced route as in the following example...
namespace :admin do
get 'dashboard' => 'dashboard#index'
end
...how can I get '/admin' to route to 'dashboard#index' as well as '/admin/dashboard'? Would the best way to do it be to define...
get 'admin' => 'admin/dashboard#index'
outside the namespace or is there a more elegant way to alias a resource?
You can make the path just / which gets stripped internally by the Rails router, and just becomes /admin. The only difference is it being within your namespace instead of outside of it.
namespace :admin do
get 'dashboard' => 'dashboard#index'
get '/' => 'dashboard#index'
end
Which produces:
admin_dashboard GET /admin/dashboard(.:format) {:action=>"index", :controller=>"admin/dashboard"}
admin GET /admin(.:format) {:controller=>"admin/dashboard", :action=>"index"}
You can also do a redirect with the built in redirect method:
namespace :admin do
get 'dashboard' => 'dashboard#index'
get '/' => redirect('/admin/dashboard')
end
Or if you want to do it outside of the namespace:
get '/admin' => redirect('/admin/dashboard')
I personally like the first example best. Keeps it within the namespace and looks very similar to the default root route so it's easy to read over while working within the Admin namespaced routes.
In Rails 4 I use:
namespace :admin do
root 'dashboard#index'
end
And you can also define your custom route for /admin/dashbaord:
namespace :admin do
root 'dashboard#index'
get 'dashboard' => 'dashboard#index'
end

Resources