Rails 3 routes for nested controllers and sub-folders - ruby-on-rails

I need some help with routes for nested controllers. I can't figure out from the Rails guide docs by myself.
I have the following controllers in a rails 3.2 app:
/app/controllers/organizations_controller.rb (class OrganizationsController)
/app/controllers/organization/events_controller.rb (class Organization::EventsController)
then, in routes.rb
resources :organizations, path: 'org' do
resources :events
member do
get 'confirm'
end
end
end
running rake routes shows (only the relevant part for my issue):
organization_event GET /org/:organization_id/events/:id(.:format) events#show
The URL is ok, the route name is also ok, but the mapping to the "controller/action" is not right. Not as I want it to be. It should be organization/events#show.
What am I missing? How can I point this route to the correct controller. I chose to put the events_controller in the organization folder, because I already have another events_controller placed in the root of the controllers folder, and they have different purposes.
Thank you

namespace :organization do
resources :events
member do
get "confirm"
end
end
end
More info here.
EDIT
Sorry, didn't understand you correctly.
resources :organizations, path: 'org' do
resources :events, :module => "organization"
member do
get 'confirm'
end
end
end
Does that fit your needs?

Related

Missing :action key on routes definition Rails

I am getting the following error:
Missing :action key on routes definition, please check your routes.
For this route
resources :groups do
post '/groups/:id/add', on: :member
end
I have looked at several other SO answers on this but am not able to find one that helps me. What action is it missing?
This is not the right way to define routes. Actually router's member/collection accepts a key-value pair to generate the route. As you are defining a member function it will be like:
resources :groups do
member do
post :add
end
end
It will generate a route like: groups/1/add
If you use collection then it will generate: /groups/add
resources :groups do
collection do
post :add
end
end
Hope you get the idea.
Or
You can define specific route for this particular action like below:
match "/groups/:id/add" => "groups#add", via: :post
Key action here means controller action. as in
resources :groups do
post '/groups/:id/add', on: :member, action: "add"
end
Rails can't infer the action from a path. But you can define the action instead and rails will automatically figure out the path:
resources :groups do
post :add, on: :member
end

How to name nested controllers and routes?

I'm working on creating a wiki app from scratch with the following organization:
Main Controller: Wiki
Nested Controller: WikiCategories
Nested Controller: WikiArticles
In my config/routes.rb I have:
resource :wiki do
resources :wiki_categories, :as => :categories
resources :wiki_articles, :as => :articles
end
I've chosen to name the categories and articles controllers as WikiCategories and WikiArticles to differentiate from other category and article controllers that I want to make in the future under a blog nesting.
This gives me the following routes:
/wiki/wiki_categories/new
/wiki/wiki_articles/new
Is there any way to rewrite the routes to be:
/wiki/categories/new
/wiki/articles/new
... while still using the WikiCategories and WikiArticles controller names?
I've chosen to name the categories and articles controllers as WikiCategories and WikiArticles to differentiate from other category and article controllers that I want to make in the future under a blog nesting.
IMO, it seems like you're bucking convention a bit. As discussed in Controller Namespaces and Routing, why not do:
namespace :wiki do
resources :categories, :articles
end
Which will give you:
wiki_categories GET /wiki/categories(.:format) wiki/categories#index
POST /wiki/categories(.:format) wiki/categories#create
new_wiki_category GET /wiki/categories/new(.:format) wiki/categories#new
edit_wiki_category GET /wiki/categories/:id/edit(.:format) wiki/categories#edit
wiki_category GET /wiki/categories/:id(.:format) wiki/categories#show
PATCH /wiki/categories/:id(.:format) wiki/categories#update
PUT /wiki/categories/:id(.:format) wiki/categories#update
DELETE /wiki/categories/:id(.:format) wiki/categories#destroy
wiki_articles GET /wiki/articles(.:format) wiki/articles#index
POST /wiki/articles(.:format) wiki/articles#create
new_wiki_article GET /wiki/articles/new(.:format) wiki/articles#new
edit_wiki_article GET /wiki/articles/:id/edit(.:format) wiki/articles#edit
wiki_article GET /wiki/articles/:id(.:format) wiki/articles#show
PATCH /wiki/articles/:id(.:format) wiki/articles#update
PUT /wiki/articles/:id(.:format) wiki/articles#update
DELETE /wiki/articles/:id(.:format) wiki/articles#destroy
Then, create namespaced controllers, something like:
app/controllers/wiki/categories.rb
class Wiki::CategoriesController < ApplicationController
...
end
and
app/controllers/wiki/articles.rb
class Wiki::ArticlesController < ApplicationController
...
end
Yes it is by specifying the controller, the resource can then be named whichever way you like.
resource :wiki do
resources :categories, controller: 'wiki_categories'
resources :articles, controller: 'wiki_articles'
end
Please see the guide for further information.
You can use the path: option as follows:
resource :wiki do
resources :wiki_categories, path: 'categories', :as => :categories
resources :wiki_articles, path: 'articles', :as => :articles
end
Which will give you:
/wiki/categories/...
/wiki/articles/...
See Translated Paths section of the guides for further details.

Rails how to make example.com/post/1 to example.com/blog/post/1

I have a blog with root
root 'posts#index'
And works best with example.com/ to example.com/posts
But what I want is something like this:
example.com/blog/posts/1.
I've tried creating blog Controller and add
resources :blog do
resources :posts
end
But this is making my routes to blog/:id/posts/:id
If you don't have the relationship between the post and the blog as you mentioned, rails gives you the freedom to declare routes as our own.
so, to make the route example.com/posts/1 to, example.com/blog/posts/1, just add a custom route at the last.
get '/blog/posts/:id', to: :show, controller: 'posts'
what this does is over rides the previous route and make this route final.
Now type rake routes and it will give the last route for you as,
GET /blog/posts/:id(.:format) posts#show
Now you can access using,
example.com/blog/posts/1
Reference for rails routing
Just to expand upon #Sravan answer. If you have multiple routes that will start with /blog/ you might want to check Rails guide on routing.
You can add something along the lines of
scope '/blog' do
resources :posts
resources :users
resources :images
end
Which will create corresponding routes under /blog/.
namespace :blog do
resources :posts
resources :users
resources :images
end
And your controller with namespace will look like this: Blog::PostsController

Rails 4: Nesting resource, change URI but not controller

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

How to force custom Rails route to use :id instead of :<model>_id

I defined the following custom Rails route in routes.rb:
resources :projects do
get 'members'
end
This results in the following route (output from rake routes):
project_members GET /projects/:project_id/members(.:format)
What I would like, though, is for the route to map to this instead (change :project_id to :id)
project_members GET /projects/:id/members(.:format)
How can I make that happen?
Is members a nested resource? If so define it as one, and understand that this is why you have :project_id in the route, because :id in a nested resource is used by the final child item - you can't have multiple nested resources all using the same variable to define their id.
resources :projects do
resources :members
end
Add in a third level of nesting and it becomes a bit clearer to explain:
resources :projects do
resources :members do
resources :colours
end
end
With this nesting you could visit app/projects/:project_id/members/:member_id/colours/:id which would be served by the colours controller, which knows that :id defines an instance of that controllers model, and any other named id's belong to other resources.
Otherwise I think you just need to define it as a member method:
resources :projects do
member do
get 'members'
end
end
This tells the route that the action members is a non-resource action belonging to an instance of project, which I think should sort you out, but be sure it's the right thing to do.
See section 2.10 of Rails Routing from the Outside In

Resources