Reputation: 41
I'm trying to do this:
List of Counties
County 1 (links to list of locations within County 1 County 2 (links to list of locations within County 2 etc
List of Locations within County 1
Location 1 (links to location page Location 2 etc
My routes are as follows:
Rails.application.routes.draw do
resources :counties do
resources :locations
end
root 'home#index'
get "/:county_name_with_prefix" => "counties#show_by_name"
get "/:location_name_with_prefix" => "locations#show_by_name"
end
My CountiesController is this:
class CountiesController < ApplicationController
before_filter :extract_county_name, :only => [:show_by_name]
**before_filter :extract_location_name, :only => [:show_by_name]**
def index
@counties = County.all
@locations = Location.all
end
def show
@county = County.find(params[:id])
@locations = Location.all
end
def show_by_name
@county = County.find_by_name(@county_name)
@locations = Location.all
render :show
end
private
def extract_county_name
@county_name = params[:county_name_with_prefix].gsub(County::ROUTE_PREFIX,"").gsub("-", " ").strip
end
**private
def extract_location_name
@location_name = params[:location_name_with_prefix].gsub(Location::ROUTE_PREFIX,"").gsub("-", " ").strip
end**
end
Counties index view is this:
<p>List of all counties</p>
<ul>
<% @counties.each do |county| %>
<li><%= link_to "Locations in #{county.name}", generate_county_url_with_prefix(county) %></li>
<% end %>
</ul>
Counties Show view is this:
<h1>Domestic Cleaning Services in <%= @county.name %></h1>
<ul>
<% @locations.each do |location|%>
<li><%= link_to "#{location.name}"**,generate_location_url_with_prefix(location) %></li>**
<%end%>
</ul>
I can get this to work if I remove the code between the **stars**
. However, what I can't figure out is how to get the list of locations to link to each individual location page - my attempts to do this are shown in the **code marked like this**
. The database tables are definitely set up ok in terms of relationships/data. Any ideas massively welcomed...
LocationsController:
class LocationsController < ApplicationController
before_filter :extract_location_name, :only => [:show_by_name]
def index
@location = Location.all
end
def show
@location = Location.find(params[:id])
end
def show_by_name
@location = Location.find_by_name(@location_name)
render :show
end
private
def extract_location_name
@location_name = params[:location_name_with_prefix].gsub(Location::ROUTE_PREFIX,"").gsub("-", " ").strip
end
end
end
Upvotes: 0
Views: 314
Reputation: 29328
Right now you have overlapping routes
get "/:county_name_with_prefix" => "counties#show_by_name"
get "/:location_name_with_prefix" => "locations#show_by_name"
These are ambiguous and thus the second will overwrite the first causing all of them to route to locations#show_by_name
.
This happens because there is no way for Rails to distinguish /county_name_here
from /location_name_here
. Does that make sense?
Also there is no need to create a method to generate the route when you can create a named_route
using as:
this will generate a method for routing using the as name plus _path. e.g. as: :hello
will create a method for hello_path
.
I would recommend something like
get "/counties/:county_name_with_prefix", to: "counties#show_by_name", as: :county_by_name
get "/locations/:location_name_with_prefix", to: "locations#show_by_name", as: :location_by_name
Then in your view you can use
<ul>
<% @locations.each do |location|%>
<li><%= link_to location.name,location_by_name_path(location_name_with_prefix: location.name) %></li>
<%end%>
</ul>
This will generate routes like /locations/location_name_here
in the links so that they work appropriately.
You could however also scope these inside your resources like so:
resources :counties do
get '/:county_name_with_prefix, to: 'counties#show_by_name', as: :by_name
resources :locations do
get '/:location_name_by_prefix', to: 'locations#show_by_name', as: :by_name
end
end
This will generate routes like
county_by_name GET /counties/:county_name_with_prefix counties#show_by_name
county_location_by_name GET /counties/:id/locations/:location_name_with_prefix locations#show_by_name
Although all of this seems unnecessary when you could just generate links like this using default routing for nested resources. e.g.
<li><%= link_to location.name,county_location_path(location) %></li>
This is because your nested resources have already created this route looking like
county_location GET /counties/:county_id/locations/:id locations#show
Which will call :county_id
and :id
on location
and route to something like
/counties/1/locations/12
Upvotes: 1
Reputation: 1139
have you already tried something like this?
<%= link_to location.name, county_location_path(@county, location) %>
Upvotes: 0