Rails 3 nested routes parameter names different - ruby-on-rails

I have a nested resource that looks like this:
resources :events
resources :attendances
post 'update_email'
end
end
and it shows me routes that look like this (left out most of the standard REST routes for brevity):
event_attendance GET /events/:event_id/attendances/:id
event_attendance_update_email POST /events/:event_id/attendances/:event_attendance_id/update_email
So, why is it that when I add new routes, they have a different id parameter?

Ack, figured this out almost immediately after posting.
The problem is that I didn't specify that it was a route for a member resource:
resources :events
resources :attendances
member do
post 'update_email'
end
end
end
produces what I wanted:
event_attendance GET /events/:event_id/attendances/:id
event_attendance_update_email POST /events/:event_id/attendances/:id/update_email

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

rails routing member and non-member nesting

Two quite similar routing settings really is confusing.
resources :authors do
resources :books
end
and
resources :authors do
member do
resources :books
end
end
As we all know, rails will generate the following routings :
writer_book GET /writers/:writer_id/books/:id(.:format) books#show
and
book GET /writers/:id/books/:id(.:format) books#show
How is this member option useful?
One can just not using member option and set params[:writer_id] in books_controller and be done with it right?
Does this will have a bad affect when the application gets bigger? What are the consequences?
The member and collection methods are meant to add additional RESTful actions to resources
resources :writers do
member do
post :favorite
end
collection do
get :unpublished
end
end
They are not intended for nesting resources
# bad
resources :writers do
member do
resources :books
end
end
# good
resources :writers do
resources :books
end
What are the consequences?
Using member here will result in the route
GET /writers/:id/books/:id(.:format)
Which means that the id param is ambigous! It could be either the id of the book or the author! Not good! Not using member would give us params[:writer_id] which we can use to fetch the parent record.
GET /writers/:writer_id/books/:id(.:format) books#show
See:
Rails Routing from the Outside In

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

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

Rails 3 routes for nested controllers and sub-folders

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?

Resources