What will be the url help in scope and namespace in rails? - ruby-on-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

Related

how to make dynamic namespace or scopes route in 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.

How to move Rails Engine's route to rails main routes?

I'm using Rails 4.2 with Rails Engine to handle my admin panel. I want to move the engine code to the main rails app and part of doing that is moving the routes.
For now, my routes in the Engine my-web-app/lib/admin/config/routes.rb is something like:
Admin::Engine.routes.draw do
resources :countries, only: [:index]
end
And at my app's routes config/routes.rb:
Rails.application.routes.draw do
.. some routes ...
mount GlobalAdmin::Engine => "/admin"
end
Now the engine's route for countries is countries_url NOT admin_countries_url but for URL you'll need to access it with something like admin/countries (this is the default behavior for the engine and I want to keep it this way).
What I did is that I moved my-web-app/lib/admin/config/routes.rb to my-web-app//config/routes.admin.rb and made it look something like:
Rails.application.routes.draw do
resources :countries, only: [:index]
end
And then in my config/application.rb I added something like this:
config.paths["config/routes.rb"] = [
Rails.root.join("config/routes.admin.rb"),
Rails.root.join("config/routes.rb")
]
The problem with this approach is that I have countries_url, however, I can't access it with admin namespace URL like admin/countries. If I add namespace admin something like:
Rails.application.routes.draw do
namespace :admin do
resources :countries, only: [:index]
end
end
Then I'll need to refer to countries url with admin_countries_url which is not the behavior I need.
Any help of how to move the routes from the engine without affecting the previous engine routes?
I'm aware that routes inside an engine are isolated from the application by default. The application and its engines can have routes with the same names, so integrating both can cause some issues, however I want to preserve the exact routes if possible and not to add a namespace and stick with the exact routes names.
Use scope instead of namespace:
Rails.application.routes.draw do
scope path: "/admin" do
resources :countries
end
end
max#MaxBook ~/p/sandbox> rails routes
Prefix Verb URI Pattern Controller#Action
countries GET /admin/countries(.:format) countries#index
POST /admin/countries(.:format) countries#create
new_country GET /admin/countries/new(.:format) countries#new
edit_country GET /admin/countries/:id/edit(.:format) countries#edit
country GET /admin/countries/:id(.:format) countries#show
PATCH /admin/countries/:id(.:format) countries#update
PUT /admin/countries/:id(.:format) countries#update
DELETE /admin/countries/:id(.:format) countries#destroy

Use of scope in rails routes

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

Rails 4 Routing conflict

i am rewritting a rails app I did some 5 years ago using rails 1.something.
When I try to browse localhost/companies/search_updates/ I get this error... I know this is a routing error because when I remove the resources :companies from router.rb the thing works fine... How can this be fixed? And do I need to manually add routes for every action I create?
Error when I try to access localhost/companies/search_updates/
The action 'show' could not be found for CompaniesController
Controler
class CompaniesController < ApplicationController
def index
#companies = Company.all
end
def search_updates
# Execute code to search for updates
# Redirect to results
end
end
Routes
resources :accounts
resources :companies
get 'companies/search_updates' => 'companies#search_updates'
search_updates.html.erb
Hello Updates!
The action 'show' could not be found for CompaniesController
Rails routes are matched in the order they are specified, so if you
have a resources :companies above a get 'companies/search_updates' the show action's
route for the resources line will be matched before the get line. To
fix this, move the get line above the resources line so that it is
matched first.
resources :accounts
get 'companies/search_updates' => 'companies#search_updates'
resources :companies
And
Resource routing allows you to quickly declare all of the common
routes for a given resourceful controller. Instead of declaring
separate routes for your index, show, new, edit, create, update and
destroy actions, a resourceful route declares them in a single line of
code.
If you have only index method (default CURD rails) on your controller, you can specific routes for it.
resources :accounts
get 'companies/search_updates' => 'companies#search_updates'
resources :companies, :only => [index]

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

Resources