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
Related
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.
I would like to use React-Router to handle the majority of my pages from the visitor part and create a Single Page Application in the mean time. However, I would like to make sure that if the user types /admin, he wouldn't get "redirected" to the root_path
So far I only managed to either pass everything to a wildcard or make "compartiments" as follows:
root 'home#index'
# example 1
get '/*path' => 'home#index'
get '/articles' => 'home#articles_index'
# example 2
get '/articles/*all' => 'home#articles_index'
# vain try 1
get '/*path' => 'home#index', except: :admin
# vain try 2
get '/*path' => 'home#index', except: '/admin'
I found out about the constraints, but I realized it's to make sure the url is correctly passed (ie, integer instead of strings) but it doesn't "blacklist" urls.
Any idea?
Thank you in advance
You can use wildcard segment with constraints for this purpose. For example:
# config/routes.rb
Rails.application.routes.draw do
root to: 'home#index'
get '*subroute', to: 'home#index', constraints: { subroute: /(?!admin|login|logout).*/ }
# all another routes below
end
This will pass any request to home#index unless there is 'admin' or 'login' or 'logout' in URL.
I want to do something like:
namespace :dashboard do
get 'speed'
get 'engine'
get 'oil'
get 'errors', :to => 'warn_system#errors', :module => false
end
Only errors link to another controller.
dashboard_speed GET /dashboard/speed(.:format) dashboard#speed
dashboard_oil GET /dashboard/oil(.:format) dashboard#oil
dashboard_engine GET /dashboard/engine(.:format) dashboard#engine
dashboard_errors GET /dashboard/errors(.:format) dashboard/warn_system#errors {:module=>false}
For the last record, I want it to be
dashboard_errors GET /dashboard/errors(.:format) warn_system#errors
What shall I do?
I am using Rails 3 if it matters.
For Rails 3, try this:
scope '/dashboard' do
get 'errors', :to => 'warn_system#errors'
end
To route to a different controller within a namespace specify the absolute path to the controller. If the warn_system controller is in the root namespace use:
namespace :dashboard do
get 'errors', :to => '/warn_system#errors'
end
Update:
Based on your comment it looks like you want to use:
namespace :dashboard do
get 'errors', :to => '/dashboard/warn_system#errors'
end
Suppose I have a model User and I want to add some dashboard namespace. So I create dashbord directory and put inside private_users_controller.rb. Now for routing I put
namespace "dashboard" do
resources :users do
member do
get "show" => "private_users#show"
end
end
end
the problem is that I only want to route the get request having this route /dashboard/users/:id/show. But rake routes shows a bunch of post, delete... routes.
How can I cut those ?
seems like you don't need any of the method from resources definition, so just add a match will be ok.
namespace "dashboard" do
match 'users/:id/show', :to => 'private_users#show'
end
if you insist using resource, then the following will work
scope '/dashboard' do
resources :users, :only => :show, :module => 'private'
end
the 'rake routes' output is like this
GET /dashboard/users/:id(.:format) private/users#show
the trailing 'show' inside the url is not needed.
namespace "dashboard" do
get "users/:id/show" => "private_users#show"
end
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