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 endWell, 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