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?
Related
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 have the following routes.rb:
resources :users
namespace :vmt do
resources :dashboards do
resources :users
resources :evaluation_units
resources :orga_units
end
end
I want to set the user in an overall context and nested in a single dashboard context within a namespace. The users-Controller is not in the namespace. So when I open the path /vmt/dashboards/1/users in browser, I get the following Routing Error
uninitialized constant Vmt::UsersController
So how can I specify, that in this resource
namespace :vmt do
resources :dashboards do
resources :users
that the controller is not in a namespace? I tried to set the controller explecitly with
resources :users, controller: 'user'
but it's still in the vmt namespace.
Using scopes will point rails to the proper url, but does not seem to provide the same useful route url helpers. We can, however, use / to point to the 'top level' controller.
Say you have two routes we want to display the users on:
/users and /admin/users
resources: users
namespace :admin do
resources :users, controller: '/users' # 'users' alone would look for a '/admin/users_controller'
end
With this, we can continue to use the url helper admin_users_path
(Note: Not a rails expert, there may be a way to create url helpers for scopes, or some other solution. Above tested on rails 5.2)
My original answer didn't work in the end, once you're inside a namespaced scope within a route you can't get out anymore.
The easiest way to re-use your logic is to create a Vmt::UsersController like so:
class Vmt::UsersController < ::UsersController
end
You can specify a different module with the module key.
For example:
resources :users, module: nil
Edit: I'm not 100% sure if this will work inside a namespace. If not, you can change it to a scope, and add the module explicitly to the other resources.
So lets consider the following in routes.rb
concern :shared_actions do
resources :courses do
resources :lessons
end
resources :users
end
my admin namespace has the following
namespace :admin do
concerns :shared_actions
get '', to:'dashboard#index', as: '/'
resources :lessons
end
and my root path '/' also shares the same concerns using
concerns :shared_actions
So what i want is,for the root path i want only index and show action for the courses path but in the admin namespace i want to have all actions for courses.
Is there a way to do that without writing explicit code for each case?
I would like to create a resourceful route on a resource member, but I can't seem to find the syntax to create the named route that I want.
namespace :admin
resources :foobars do
get :attribute, on: :member, as: :attribute
end
end
This will provide a route method called:
attribute_admin_foobar_path
I would like it to say:
admin_foobar_attribute_path
The only other way I can think of would be to reject the resources block and create a single route:
namespace :admin
resources :foobars
get 'foobars/:id/attribute', as: :foobar_attribute
end
However, I don't like this approach because it forces me to duplicate the routing structure of already existing routes...not very DRY.
Is there a way that I can create the route name that I want while still using the resources routing block?
If you do it like this:
namespace :admin do
resources :foobars do
get :attribute
end
end
You will get:
admin_foobar_attribute GET /admin/foobars/:foobar_id/attribute(.:format) admin/foobars#attribute
That is admin_foobar_attribute_path.
I currently have these routes set up:
namespace :api do
namespace :v1 do
resources :users do
match 'api/v1/users/all'
end
resources :sessions
end
end
I'm trying to set up a custom actio nin my users controller called "all".
How do I get the route for that to match? I've tried these, and get no route errors:
resources :users do
match 'api/v1/users/all' => "users#all" (also "api/v1/users#all" and "api_v1_users#all"
end
What is the route that will enable me to connect with my custom action?
Thanks
You need to add a collection
namespace :api do
namespace :v1 do
resources :users do
collection do
get 'all'
end
end
resources :sessions
end
end
The namespace and resources method calls create the hierarchy; a route nested with the resource :users block will take on the path of it's ancestors. The collection creates nested routes on the resource collection instead of single instances of the resource.
/api/v1/users/all
Recommended Reading: http://guides.rubyonrails.org/routing.html#adding-collection-routes