As an example a person has many tasks:
class Person < ActiveRecord::Base attr_accessible :name has_many :tasks endand every task belongs to a person:
class Task < ActiveRecord::Base attr_accessible :name, :person_id belongs_to :person endThe original config/routes.rb contains the routes to the resources:
resources :people resources :tasksand in the view people/show.html.erb there is a link to the form for a new task, which is for a very specific person:
<%= link_to "New task for #{@person.name}",
new_task_path(:person_id => @person.id) %>
The generated result looks like:
New task for DavidThe additional parameter is required for setting the association to the person in the tasks_controller.rb, but has to be commited:
class TasksController < ApplicationController
def new
@task = Task.new :person_id => params[:person_id]
end
end
Well, the parameter passing works, but is awful.Please note the URL "/tasks/new?person_id=1".
It is not resourceful.
It does not clarify the association between Person and Task.
But an URL like "/people/1/tasks/new" definitely would give a clear intention about the association. In Ruby on Rails there is a way to achieve just that: nested routes.
The refactored config/routes.rb:
resources :people do resources :tasks endDoing "rake routes" in the console responds with:
| tasks | GET | /people/:person_id/tasks(.:format) | tasks#index |
| POST | /people/:person_id/tasks(.:format) | tasks#create | |
| new_person_task | GET | /people/:person_id/tasks/new(.:format) | tasks#new |
| edit_person_task | GET | /people/:person_id/tasks/:id/edit(.:format) | tasks#edit |
| task | GET | /people/:person_id/tasks/:id(.:format) | tasks#show |
| PUT | /people/:person_id/tasks/:id(.:format) | tasks#update | |
| DELETE | /people/:person_id/tasks/:id(.:format) | tasks#destroy |
<%= link_to "New task for #{@person.name}",
new_person_task_path(@person) %>
The URL helper method generates the link:
New task for DavidThe intention of the link is clear: a new task resource belonging to the person having the id "1".
Nested routes also can be generated by polymorphic routes:
<%= link_to "New task for #{@person.name}",
[:new, @person, :task] %>
Finally I highly recommend not to nest the routes deeper than 1 nesting. URLs like "/company/1/buildings/2/places/2/people/5/tasks/2" are nasty likewise.
Supported by Ruby 1.9.3 and Ruby on Rails 3.2.3
Keine Kommentare:
Kommentar veröffentlichen