Rodolphe Geant
Rodolphe Geant

Reputation: 89

Unable to route to child resource - Nested routes

I've been banging my head against this one for few days now ......

my routes.rb file looks like this:

resources :vehicles do
 member do
   resources :services  
 end
end

my service.rb file shows:

class Service < ActiveRecord::Base
  belongs_to :vehicle
end

my vehicle.rb file shows:

class Vehicle < ActiveRecord::Base
  has_many :services, :dependent => :destroy
end

Here is services_controller.rb

class ServicesController < ApplicationController

  def index
    @vehicle = Vehicle.find(params[:id])
    @services = @vehicle.services.order('created_at DESC')
  end

  def show
    @vehicle = Vehicle.find(params[:id])
    @service = Vehicle.services.find(params[:service_id])
  end

  def new
    @vehicle = Vehicle.find(params[:id])
    @service = @vehicle.services.new
  end 

  def create
    @vehicle = Vehicle.find(params[:id])
    @service = @vehicle.services.build(service_params)
    if @service.save
      redirect_to @vehicle
    else
      render :new
    end
  end


  private
    def service_params
       params.require(:service).permit(:service_option, :odometer, 
   :current_service, :price, :comments, :next_service)
  end

end

And here is the services#index

<h1>Services</h1>


<% @services.each do |s| %>
  <%= link_to "Details", service_path(s) %>
  <%= s.created_at %>
  <%= s.service_option %>
  <%= s.odometer %><br>
<% end %>

Clicking on the "Details" link or manually entering the URL

http://localhost:3000/vehicles/2/services/7

gives my systematically the same routing error:

ActiveRecord::RecordNotFound in ServicesController#show Couldn't find Vehicle with 'id'=7

Extracted source (around line #10):

def show
   @vehicle = Vehicle.find(params[:id])
   @service = Vehicle.services.find(params[:service_id])
end

It passes a SERVICE ID to a vehicle objet / variable and I don't know why!

Thanks a million!

Upvotes: 0

Views: 56

Answers (1)

Pavan
Pavan

Reputation: 33542

In your services#show method you are fetching the vehicle and service with wrong params. Also Vehicle.services is wrong, it should be @vehicle.services

def show
  @vehicle = Vehicle.find(params[:vehicle_id])
  @service = @vehicle.services.find(params[:id])
end

Update:

You should remove member in the routes, else it will produce the routes like

service GET  /vehicles/:id/services/:id(.:format)  services#show

which are irrelevant

resources :vehicles do
  resources :services  
end

So now you will have routes like

service GET  /vehicles/:vehicle_id/services/:id(.:format)  services#show

which are relevant and you can fetch the vehicle with params[:vehicle_id] and service with params[:id]

Don't forget to change the route helpers. For instance service_path will become vehicle_service_path

<%= link_to "Details", vehicle_service_path(@vehicle,s) %>

Upvotes: 1

Related Questions