Reputation: 3289
I've created a small test app utilizing the Has-Many Through Association method but I can seem to get link_to
to work with within my nested routes.
error message
No route matches {:action=>"show", :controller=>"categories", :location_id=>#<Category id: 1, name: "parties", created_at: "2017-11-01 17:40:25", updated_at: "2017-11-01 17:40:25">}, missing required keys: [:id]
location.rb
class Location < ApplicationRecord
belongs_to :product
belongs_to :category
end
category.rb
class Category < ApplicationRecord
has_many :locations
has_many :products, through: :locations
end
product.rb
class Product < ApplicationRecord
has_many :locations
has_many :categories, through: :locations
end
routes.rb
Rails.application.routes.draw do
resources :locations do
resources :categories do
resources :products
end
end
root :to => 'locations#index'
end
categories/index.html
...
<% @categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<td><%= link_to 'Show', location_category_path(category) %></td>
<td><%= link_to 'Edit', edit_location_category_path(category) %></td>
<td><%= link_to 'Destroy', location_categories_path(category), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
...
127.0.0.1:3000/rails/info/routes
location_category_products_path GET /locations/:location_id/categories/:category_id/products(.:format)
products#index
POST /locations/:location_id/categories/:category_id/products(.:format)
products#create
new_location_category_product_path GET /locations/:location_id/categories/:category_id/products/new(.:format)
products#new
edit_location_category_product_path GET /locations/:location_id/categories/:category_id/products/:id/edit(.:format)
products#edit
location_category_product_path GET /locations/:location_id/categories/:category_id/products/:id(.:format)
products#show
PATCH /locations/:location_id/categories/:category_id/products/:id(.:format)
products#update
PUT /locations/:location_id/categories/:category_id/products/:id(.:format)
products#update
DELETE /locations/:location_id/categories/:category_id/products/:id(.:format)
products#destroy
location_categories_path GET /locations/:location_id/categories(.:format)
categories#index
POST /locations/:location_id/categories(.:format)
categories#create
new_location_category_path GET /locations/:location_id/categories/new(.:format)
categories#new
edit_location_category_path GET /locations/:location_id/categories/:id/edit(.:format)
categories#edit
location_category_path GET /locations/:location_id/categories/:id(.:format)
categories#show
PATCH /locations/:location_id/categories/:id(.:format)
categories#update
PUT /locations/:location_id/categories/:id(.:format)
categories#update
DELETE /locations/:location_id/categories/:id(.:format)
categories#destroy
locations_path GET /locations(.:format)
locations#index
POST /locations(.:format)
locations#create
new_location_path GET /locations/new(.:format)
locations#new
edit_location_path GET /locations/:id/edit(.:format)
locations#edit
location_path GET /locations/:id(.:format)
locations#show
PATCH /locations/:id(.:format)
locations#update
PUT /locations/:id(.:format)
locations#update
DELETE /locations/:id(.:format)
locations#destroy
root_path GET /
locations#index
Upvotes: 0
Views: 455
Reputation: 7136
For the route:
location_category_path GET /locations/:location_id/categories/:id(.:format)
You need several things, the location id object and category id object:
<!-- /locations/:location_id/categories/:id -->
<%= link_to 'Show', [{location_id}, {category_id}] %>
Upvotes: 1
Reputation: 6603
Just to add to Arslan' answer.
You'll probably need to set @location
in your controller if you don't have yet.
app/controllers/categories_controller.rb
class CategoriesController < ApplicationController
def index
@location = # your code here
end
end
app/views/categories/index.html.erb
<% @categories.each do |category| %>
<tr>
<td><%= category.name %></td>
<td><%= link_to 'Show', location_category_path(@location.id, category.id) %></td>
<td><%= link_to 'Edit', edit_location_category_path(@location.id, category.id) %></td>
<td><%= link_to 'Destroy', location_categories_path(@location.id, category.id), method: :delete, data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
For routes URL parameters, you can use either:
location_category_path(@location.id, category.id)
Which follows the order of your routes (which is :location_id
then :id
) when you do bundle exec rake routes
, or you can also be specific like the following:
location_category_path(location_id: @location.id, id: category.id)
Upvotes: -1
Reputation: 17802
location_category_path GET /locations/:location_id/categories/:id(.:format)
As you can see here, the route: location_category_path
required two things: :location_id
& :id
(the id
of category you want to refer to).
In your case, you are only specifying one, and not the other. You also need to specify :location_id
.
There is a shorter way as well to write this URL: [location_id, category_id]
. Just write an array with both ids starting with location_id
.
Upvotes: 1