how to make dynamic namespace or scopes route in rails - ruby-on-rails

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.

Related

What will be the url help in scope and namespace in rails?

Please tell me what will be the url helpers for the following code?
scope module: 'admin' do
resources :articles, :comments
end
and
scope '/admin' do
resources :articles, :comments
end
and
namespace :admin do
resources :articles, :comments
end
As per the rails guide document here - Controller namespace and routing
1.
If you want to route /articles (without the prefix /admin) to Admin::ArticlesController, you can specify the module with a scope block
the path will be like
GET articles_path #index action
GET comments_path #index action
If instead, you want to route /admin/articles to ArticlesController (without the Admin:: module prefix), you can specify the path with a scope block:
this will give the following path but the controller will contain Admin:: prefix
GET admin_articles_path # index action
GET admin_comments_path #index action
with namespace, the route will prefix by admin as well as controller needs to have Admin:: module prefix
GET admin_articles_path # index action
GET admin_comments_path #index action
Running the following commands on a console will return the available routes for your application.
rails routes | grep article
rails routes | grep comment

Prevent a route from matching on the wrong namespace?

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?

add subdomain if namespace present

Not sure if my topic title is correct, but here is my question
I have namespace called :admin, so it looks like mysite.com/admin. In this section i have some links, that pointing to controllers inside this namespace. But since we have subdomain admin, and my namespace :admin as well, i'd like to all links that are being generated by routes.rb to prepend string admin., so the link would look like admin.mysite.com/admin/some_other_path
I've tried to add constraints to routes.rb, but that didn't work for me
But since we have subdomain admin, and my namespace :admin as well,
i'd like to all links that are being generated by routes.rb to prepend
string admin.
Routes
In your routes, you should have this:
constraints({ subdomain: "admin" }) do
namespace :admin do
# routes here
end
end
If you wanted to have no path for your admin namespace (I.E admin.domain.com/some_other_path), you can do this:
constraints({ subdomain: "admin" }) do
namespace :admin, path: "" do
# routes here
end
end
--
URL
When using URLs, you have to use the _url helpers (not _path). We literally just discovered this yesterday - the _path helpers only work to append relative paths to your url; the _url gives you a totally fresh url
This means if you have a route as follows:
admin_root_path "admin/application#index, constraints => {subdomain: "admin"}
You'll call this with this route helper:
<%= link_to "Admin", admin_root_url %>
This will prepend the required subdomain for you when calling links etc
you can do:
constraints subdomain: 'admin' do
namespace :admin do
# ...
end
end
Define routes in routes.rb under admin namespace like this
namespace :admin, path: '/', constraints: { subdomain: 'admin' } do
constraints(Subdomain) do
# your routes
end
end
Routes defined under this block will always come under admin in link, e.g., /admin/some_other_path
To add subdomain to the admin namespace take a look at this question
Rails namespace admin on custom subdomain

Routing Error: uninitialized constant

I'm trying to set up routes for a mobile API, which should have a versioned api-path. I already could make the mobile Auth work, which is implemented in a separate Controller AuthController located in /controllers/api/v1/mobile/.
Usage example:
myapp.com/api/v1/mobile/auth
But now I want to register my existing ressources-Controllers to this path-pattern as additional api-routes. Concrete: this would be the TasksController located at /controllers/tracker/tasks_controller.rb. So I added a mobile route to the routes-definition:
# routes.rb
namespace :tracker, path: 'timetracking' do
resources :tasks, 'jobs'
end
namespace :api do
namespace :v1 do
namespace :mobile do
resources :auth, :only => [:create, :destroy]
namespace :tracker do #added mobile route
resource :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
end
end
end
But when I call myapp.com/api/v1/mobile/tracker/tasks it results in an error-message:
Routing Error
uninitialized constant Api::V1::Mobile::Tracker
I especially added the alias :mobile_tasks to this route, to avoid any conflicts with the original tasks-route above. Any ideas, how to set the controller properly for this route?
Update#1
Defining this route as a scope instead of a namespace, didn't work aswell.
scope "/api/v1/mobile/tracker" do
resources :tasks, controller: 'tracker/tasks', as: :mobile_tasks
end
But this time, it didn't even resolve the route-path itself.
Routing Error
No route matches [GET] "/api/v1/mobile/tracker/tasks"
I assume it might be a problem, that my additional mobile-api route tries to point to a completely different namespace tracker.
According to http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing you should use scope instead of namespace.
If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use:
scope "/admin" do
resources :posts, :comments
end
Adding this answer to get clarity on namespace & scope.
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.
# config/routes.rb
namespace :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
When we add scope, it will just map the controller action for the given scope patterns. No need to define controller under any module.
# config/routes.rb
scope :admin do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) posts#index
Note that, controller is just posts controller without any module namespace.
If we add a path option to scope it will map to the controller with the path option specified as follows
# config/routes.rb
scope module: 'admin', path: 'admin' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
admin_posts GET /admin/posts(.:format) admin/posts#index
Note that the controller now is under admin module.
Now, if we want to change the name of path method to identify resource, we can add as option to scope.
# config/routes.rb
namespace module: 'admin', path: 'admin', as: 'root' do
resources :posts, only: [:index]
end
# rake routes
Prefix Verb URI Pattern Controller#Action
root_posts GET /admin/posts(.:format) admin/posts#index
You can see the change in the Prefix Verb.
Hope it helps others.
Late answer, but still might be helpful:
scope '/v1' do
resources :articles, module: 'v1'
end
controller
# app/controller/v1/articles_controller.rb
class V1::ArticlesController < ApplicationController
end
Now you should be able to access this url:
http://localhost:3000/v1/articles

Route a controller to namespace :admin to /admin

I feel like this may be a dumb question, but it's late and my head is melting a bit.. So I appreciate the assistance.
I'm trying to map the url http://localhost:3000/admin to a dashboard controller but i'm epically failing. Maybe this isn't even possible or the completely wrong idea but anyway my routes looks like this and yes
namespace :admin do
resources :dashboard, { :only => [:index], :path => '' }
...
end
and my simple dashboard_controller.rb
class Admin::DashboardController < ApplicationController
before_filter :authenticate_user!
filter_access_to :all
def index
#schools = School.all
end
end
and my view is located in views/admin/dashboard/index.html.erb
thanks for any input
If all you're trying to do is route /admin to that dashboard controller, then you're overcomplicating it by namespacing it like that.
Namespacing with a nested resource like that would mean that it would be /admin/dashboards for the :index action instead of having a clean /admin route (and you can verify that by running rake routes at the command line to get a list of your routes).
Option 1: You meant to namespace it like that
# putting this matched route above the namespace will cause Rails to
# match it first since routes higher up in the routes.rb file are matched first
match :admin, :to => 'admin/dashboards#index'
namespace :admin do
# put the rest of your namespaced resources here
...
end
Option 2: You didn't mean to namespace it like that
Route:
match :admin, :to => 'dashboards#index'
Controller:
# Remove the namespace from the controller
class DashboardController < ApplicationController
...
end
Views should be moved back to:
views/dashboards/index.html.erb
More info: http://guides.rubyonrails.org/routing.html
Regarding to http://guides.rubyonrails.org/routing.html I prefer this
namespace :admin do
root to: "admin/dashboards#index"
resources :dashboard
end
Try this:
namespace :admin do
root to: 'users#index' # whatever. Just don't start with /admin
#resources :dashboards <= REMOVE THIS LINE !
end

Resources