To Examples
NestedRoutes Example
Directions
- Create a Rails project named NestedRoutes with two scaffold-based
controllers with model names Pet and Owner. Include
owner_id as one of the fields for Owner.
For example, you could use these fields:
Owner name:string phone:string
Pet name:string animal_type:string owner_id:integer
- Set up a one-to-many relationship between Owner and
Pet by adding
has_many :pets
in the Owner model and
belongs_to :owner
in the Pet model.
- Because every owner owns a collection of pets, the pets resource can be
thought of as being nested inside the owners resource. To configure pets as a
resource nested inside of owners, change the resource declarations in
config/routes.rb from
resources :owners
resources :pets
to
resources :owners do
resources :pets
end
- After making this change, the owners are still accessed as before
because they are not nested in any other resource.
- However, we should be able to access the pets according to their
owners as shown in
the Nested RESTful Routes Table.
To show pet number 3 of owner 5, use this URL:
http://localhost:3000/owners/5/pets/3
- After making the change in the routes file, we need to modify the
Pets controller so that it functions correctly. The rest of this document
describes the changes that must be made for pets to function as a nested
resource within owners.
- Get the owner id from the route
- Enter this code at the bottom of the controller after the private
get_pet method:
def get_owner
@owner = Owner.find(params[:owner_id])
end
- Invoke the get_owner method at the beginning of the
controller before the before_filter :set_pet statement:
before_filter :get_owner
- Update the view routes.
In the Pet views (index, show, new, edit), replace the
scaffold-generated named routes in the
first table by the named nested routes
in the second table.
- Update the find statements in the Pets controller.
Because the pets are nested within owners, we don't want all pets;
we want only the pets that belong to the owner with id=owner_id.
- In the index method, replace
@pets = Pet.all
by
@pets = @owner.pets
In the private set_pet method at the bottom of the
controller, replace
@pet = Pet.find(params[:id])
by
@pet = @owner.pets.find(params[:id])
In the new method, replace
@pet = Pet.new
by
@pet = @owner.pets.build
In the create method, replace
@pet = Pet.new(params[:pet])
by
@pet = @owner.pets.build(pet_params)
Update the form_for statement
In _form.html.erb, replace the @pet object in the
form_for statement
by the array [@owner, @pet].
Update the redirect URLs in the controller. In the Pet controller, replace the
scaffold-generated named routes in the
first table by the named nested routes
in the second table.
Localhost URL to view the owners index view:
http://localhost:3000/owners