I'd like to be able to namespace my controllers, without namespacing the urls. So for example, I'd like to be able to have a controller in a folder like:
app/controllers/abc/my_controller
and another in
app/controllers/def/my_controller
I don't want the routes to contain /abc, or /def, instead I'm using constraints to disambiguate between them. What's the most Rails way to achieve this?
Some background: I'm building a multi-domain site, the constraint is the request domain.
You can use a scope with a block.
scope :module => "abc" do
resources :my_controller
end
scope :module => "def" do
resources :my_controller
end
or pass it individually
resources :my_controller, :module => "abc"
resources :my_controller, :module => "def"
More information in the routes guide. The information on scopes is just under the table in the section I linked to.
routes.rb:
resources :resource_name, module: 'ControllerNameSpace', constraints: {subdomain: 'foo'}
Rails guide link
Related
What is the difference between resources and namespace?
I have a Rack app inside a gem that I want to call from the Rails app.
namespace :app do
get 'go', to: Gem::Controller.new
end
Since I have controller called AppController, can I use this one?
resources :app do
collection do
get 'go', to: Gem::Controller.new
end
end
Which way is better?
As per the Rails guide routing section
Resources:
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.
Namespace:
You may wish to organize groups of controllers under a namespace. Most
commonly, you might group a number of administrative controllers under
an Admin:: namespace. You would place these controllers under the
app/controllers/admin directory, and you can group them together in
your router.
Eg:
namespace :admin do
resources :articles, :comments
end
But, I think what you meant was to choose between collection and namespacing.
It's like this, namespacing would be a better option if you are planning to have more routes for that app. Else, you can just use it as a collection.
resources is a shortcut for generating seven routes needed for a REST interface.
so resources :app would generate the following seven routes(patch and put routes are same):
get "apps" => "apps#index", :as => 'apps'
get "apps/:id" => "apps#show", :as => 'app'
get "apps/new" => "apps#new", :as => 'new_app'
post "apps" => "apps#create", :as => 'apps'
get "apps/:id/edit" => "apps#edit", :as => 'edit_app'
patch "apps/:id" => "apps#update", :as => 'app'
put "apps/:id" => "apps#update", :as => 'app'
delete "apps/:id" => "apps#destroy", :as => 'app'
and then it would generate another route because of get 'go', to: Gem::Controller.new:
/apps/go
In case of namespace the apps seven REST routes won't be created but a named route for apps/go would be generated.
Routes.rb
scope :module => :abc do
namespace :old_namespace do
resources :posts
end
end
How Can I change the old_namespace to new_namespace, So that in my URLS I should see the new_namespace. I have too many views where I have used the previous routes with *_path and *_url methods. I dont want to change them for now. Is there any Rails Way to do this.
Things I have Tried,
scope :module => :abc do
namespace :new_namespace,:as => :old_namespace do
resources :posts
end
end
This Gives me the change in the URLS I need but Also, Gives me and Error
uninitialized constant Abc:NewNamespace
This is expecting me to have constant Abc:NewNamespace, ALthough I want this to use the Old Constant, Abc:OldNamespace, Something Similiar to :controller option in the resources for the namespace
You Simply do this:
scope module: 'abc/OldNamespace' do
resources :posts, path: 'new_namespace/posts'
end
here you are saying,
use abc::OldNamespace
use new_namespace/posts as URL path for posts resource.
This should work too, let me if this doesn't
I used this,
namespace :new_namespace,:as => :old_namespace, :module => :old_namespace do
This is working now.
I have 2 namespaces, api and v1
I have accounts and users as resources.
I want to map the routing as follows for all my resources:
/api/v1/:account_id/:resource/:id
i.e:
/api/v1/1/users/2
In the example 1 stands for account id and 2 stands for user id.
How do I accomplish this?
This does away with namespaces, such that you don't need to append API::V1:: to each controller, or bury view files in subdirectories. The following uses normal, top-level controllers and views:
scope '/api/v1/:id', :as => 'account' do
resources :users
end
If you want to keep all the namespace structure stuff, do this:
namespace 'api' do
namespace 'v1' do
scope '/:id', :as => 'account' do
resources :users
end
end
end
This problem has taken all day of mine...
Well;
I'm just trying to put all of my administration pages inside an /admin directory and to receive them via domain/admin style only. I've tried to make it run with this guide.
According to that official guide, what I'm looking for is using scope in my routes.rb file. BECAUSE, I have used named routes tones of times inside my pages. I do not want my program_path named route to change admin_program_path since I have 28 different usage of it.
So I'm supposed to use scope instead of namespace.
Issue is: I can not make scope work with my project.
Here is my routes.rb
scope "/admin" do
get "access/login"
get "access/index"
match "access/login_attempt", to: "access#login_attempt"
match "access/logout", to: "access#logout"
resources :admin_users
root to: 'programs#index'
resources :programs
resources :program_categories
resources :program_subcategories
resources :articles
resources :pictures
match '/kategoriler/:id' => 'program_categories#show'
match '/kategoriler' => 'program_categories#index'
match '/kategori/yeni' => 'program_categories#new'
match 'program/yeni' => 'programs#new'
match 'programlar' => 'programs#index'
match '/progam_categories/select_category/:program_id' => 'program_categories#select_category'
match '/program_subcategories/select_subcategory' => 'program_subcategories#select_subcategory'
match '/program_subcategory/add_subcategory' => 'program_subcategories#add_subcategory'
end
Here is my controller beginning :
class ProgramsController < ApplicationController
Just like told here:
If you want to route /admin/posts to PostsController (without the Admin:: module prefix), you could use
scope "/admin" do
resources :posts, :comments
end
As a result, what am I getting?
This error message:
Routing Error
uninitialized constant ProgramsController
Whichever controller I try to access, error changes that way.. Such like uninitialized constant ProgramCategoriesController , uninitialized constant ProgramSubcategoriesController etc...
I've tried to place application_controller both inside admin folder and root of controllers directory... No way.
Where is my mistake here? :(
Thanks in advance...
Try with :module parameter:
scope '/admin', :module => 'admin' do
# ...
end
The assumption is that your controllers are in Admin module namespace, so they start with 'Admin::'.
[EDIT]
It is response to your problem in comments below about path conflicts. You can use :as parameter, for example:
scope '/admin', :module => 'admin', :as => 'admin' do
# ...
end
You can check it with rake routes. All routes in the admin scope should now begin with 'admin_'
In routes.rb, I'm using resources to declare all common routes for a controller:
resources :photos
This creates URLs which look like this:
http://example.com/photos
http://example.com/photos/new
...
How do I remove photos from the URLs? That is, how do I map this controller to the root of the application?
You can route a resourceful controller to the root by adding the path option:
resources :photos, :path => "/"
And, of course, this can still be extended in the usual way;
resources :photos, :path => "/" do
member do
get 'view_original_size'
end
end
For more information, see Module
ActionDispatch::Routing::Mapper::Resources > resources > Supported options in the API documentation.