I'd like to have a namespace in Rails where the module name in code is different than the path name that user sees in the URL.
One can make a namespace in routes like so:
namespace :admin_ui do
resources :posts
end
and this will match /admin_ui/posts to AdminUI::PostsController.
How can I make this namespace match the path /admin, but use module AdminUI?
Found it:
namespace :admin_ui, path: 'admin' do
resources :posts
end
Related
I'm following a tutorial on Dookeeper and Devise gems in Rails, in one point of the video, the author creates the following routes:
namespace :api do
namespace :v1 do
resources:books
end
end
scope :api do
scope :v1 do
use doorkeeper do
skip_controllers:authorizations,:applications,:authorized_applications
end
end
end
I don't quite understand what's the point of the namespace and scope in point... They complement each other or are separated things and why do I have to use?
Thanks a lot!
Here's a helpful overview.
In short (my emphasis added):
When you use namespace, it will prefix the URL path for the specified resources, and try to locate the controller under a module named in the same manner as the namespace.
When using scope without any options and only a scope name, it will just change the resources path.
So scope is useful for making a route match namespace when there aren't controllers with matching names.
namespace :api do
namespace :v1 do
resources:books
end
end
Gives you a base route of "/api/v1/books" but requires a Api::V1::BooksController
scope :api do
scope :v1 do
use doorkeeper do
skip_controllers:authorizations,:applications,:authorized_applications
end
end
end
Gives doorkeeper routes that start with "api/v1" but without trying to match to an Api::V1::Doorkeeper class.
I am trying to make admin route with namespace but it doest trigger to the route
I run rails g controller admin
it created the file app/controllers/admin_controller.rb , app/views/admin/index.html.haml
my namespace look like this
namespace :admin do
controller :admin do
get '/', :index
end
end
it doesn't trigger to localhost:3000/admin it said not found for that route
any idea ??
namespace not only adds a path prefix but it also adds a module nesting to the expected controller. For example:
namespace :blog do
resources :posts
end
Will create the route /blog/posts => Blog::PostsController#index.
In your example Rails expects the controller to be defined as:
# app/controllers/admin/admin_controller.rb
module Admin
class AdminController
# GET /admin
def index
end
end
end
If you just want to add a path prefix or other options to the routes without module nesting use scope instead:
scope :admin, controller: :admin do
get '/', action: :index
end
This will route /admin to AdminController#index
But if this just a one off route you could just write:
get :admin, to: 'admin#index'
Your controller path needs to be in the admin namespace.
So the filename for the admin controller needs to be app/controllers/admin/admin_controller.rb.
I am making a custom admin panel in a namespace "admin".
I have resources "courses" within that namespace.
But I would also like a route to "courses" that is not in that namespace:
eg: BOTH localhost:3000/admin/courses AND localhost:3000/courses
It's OK if this requires different controllers.
My concern is that its not really DRY if i have both resources for the same route.
namespace admin do
resources :courses
end
and just
resources :courses
Is there a way to have one resource be shared between namespace and without namespace, or is the example above the way to go?
Oh wait ! There's also the possibility to use concerns !
concern :shared_actions do
resources :courses
resources :something_else
end
namespace :admin do
concerns :shared_actions
end
concerns :shared_actions # Will add it to the root namespace ^^
EDIT : apparently this is what this guy also tried to do :D
I'm not really sure I understand what you mean, but
namespace :something is actually a shorthand for scope :something, module: :something, as: :something
scope :something will add /something/ as a URL prefix
scope module: :something will add /something as a controller prefix (controllers will be fetched under controlelrs/something/the_controller.rb
scope as: :something will add the something as a prefix for path helpers
Now it's totally fine to have both in your routes
resources :courses
# Will generate "/courses/", "/courses/new", "/courses/1/edit", ...
# And will point to `controllers/courses_controller.rb`
namespace :admin do
resources :courses
end
# Will generate "/admin/courses/", "/admin/courses/new", "/admin/courses/1/edit", ...
# And will point to `controllers/admin/courses_controller.rb`
Does this answer your question ?
I have an API with an admin namespace that has many of the same routes as the parent namespace:
App::Application.routes.draw do
namespace :api do
resources :posts
namespace :admin do
resources :posts
end
end
end
Whenever I try to navigate to /api/admin/posts, I hit the controller action for /api/posts.
Is it possible to prevent matching the first route when I am in fact trying to hit the admin namespace?
I am calling a custom method within a namespaced route.
# config/routes.rb
namespace :v1 do
some_custom_method :users
end
Within some_custom_method I would like to access the namespace (v1). How?