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.
Related
I am trying to place my tasks into my dashboard/admin routes, for example rather than todos/, todos/new, etc. I would like dashboard/todos/, dashboard/todos/new etc. etc.
I have tried to do that here like so;
namespace :dashboard do
resources :todos
end
Though this also changes the controller, which I don't want - I only want to nest the todos inside of the dashboard controller
Can anyone point me in the right direction please?
You can use scope or path as described in the Rails Guides
scope '/dashboard' do
resources :todos
end
or
resources :todos, path: '/dashboard/todos'
This will generate the routes with the path /dashboard/todos which maps to todos_controller
If you want to route /admin/todos to TodosController you can use scopeinstead of namespace:
scope '/admin' do
resources :todos
end
You could check the rails documentations about this point : http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
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 was reading Rails routes guide and came to this part:
If you want to route /posts (without the prefix /admin) to Admin::PostsController, you could use:
scope module: 'admin' do
resources :posts, :comments
end
Ok I understood this part, it says if we use scope the way it shows us, instead of for example /admin/posts we can directly say /posts
But I didn't underatand the second part below: What does this one do?
If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use:
scope '/admin' do
resources :posts, :comments
end
How about this:
Use if you want to have controller in namespace ONLY, but don't want namespaced url for this controller
Use if you want namespaced url ONLY but not controller
I am playing with Rails 4 in a test application. I have an arbitrary URL that isn't standard like a resources :foo type URL. Ideally the end result I'd like is to be able to go to:
/contests/:id/enter
In views, it would be great if I can then set a link using a named helper such as:
edit_contests_enter(:id)?
What would be the best way to define the route above so I can use the helper path with an arbitrary URL like the one above? It doesn't necessarily have to be edit_contests_enter(:id) but as long as the helper path leads to the URL as suggested above, that would be fantastic.
I assume that your contest is a resource, and when your visitor goes to /contests/:id/enter you want them to create an object user <=> contest. Let's call it participation.
Now participation is exactly like any other resource in your Rails app, so you'd have a routes.rb file looking like
resources :contests do
resources :participations
end
You don't want people to do anything other than create a participation, like edit or destroy them. And perhaps you want a nice URI like /contests/:id/enter. All you have to do is
resources :contests do
resources :participations, :only => [:new, :create]
get "enter" => "participations#new"
end
Doing such will give you a routes helper named contest_enter. In your participations#new form, you'll POST as usual to /contests/:id/participations.
If you have a resources block for :contests, you could just define a new "member" route on the ContestsController using:
resources :contests do
member do
get :enter
end
end
And that would automatically generate you a named member route, the name of which you could find by running rake routes.
I'm trying to create a namespaced API in rails and am running into an issue
# Resources
resources :users do
resources :contacts
end
#==========================================>
# API namespacing and routing
#==========================================>
namespace :api do
namespace :v1 do
# =======================>
# Resources -> Users
# Resources -> Contacts
# =======================>
resources :users do
resources :contacts
end
# =======================>
# Resources -> Messages
# Resources -> Transcriptions
# =======================>
resources :messages do
resources :transcriptions
end
end
end
I want to have my html-responding version of the resource outside of the 'api' namespace (i.e. in the regular app/controllers/users_controller.rb area) but my json-responding inside the namespace.
However when I point my url at the "/api/v1/users.json" link it utilizes the controller specified by the OUTSIDE resources app/controllers/users_controller rather than the one I put in app/controllers/api/v1/users_controller.
Am I only allowed one resources reference despite it being namespaced differently?
Why exactly is this happending
Your routing definitions look ok. The first thing I'd check is what routes are generated by your rails router by running:
$ bundle exec rake routes | grep users
You should have your defined users routes mapped to their respective URL structure. If something's amiss then your routes aren't probably defined correctly. Which i doubt in your case.
Another possible issue might be your controller class name in your namespaced users controller. So your users controller under app/controllers/api/v1 should be
class Api::V1::UsersController < ApplicationController
....
end
Look at the Rubygems.org source which has the same kind of structure you're trying to implement.
your controller should look like
module Api::V1
class UserController < ActionController::Base
...
end
end