I have a School
model and rather than have the url at schools/1
I would like to have the url at localhost:3000/IL/city/school_name
.
I followed this guide to create the custom routes using a slug, but the end result is a url that looks like this:
http://localhost:3000/schools/IL%2Fcicero%2Fabe-lincoln-elem-school
I would like to do two things: 1. drop 'schools' from the route and 2. Replace %2F with "/".
I've created the slugs in a rake task like this:
def to_slug(string)
string.parameterize.truncate(80, omission: '')
end
slugs = []
School.find_each do |school|
slug = "#{school.state}/#{to_slug(school.city)}/#{to_slug(school.name)}"
if slugs.include?(slug)
slug = slug + "-2"
p "Same Name"
end
p slug
slugs << slug
school.slug = slug
school.save
end
In my school model:
def to_param
slug
end
In my routes.rb:
resources :schools, param: :slug
Finally, in my controller in the show action:
@school = School.find_by_slug(params[:slug])
I am a beginner and way beyond my skill set. I've done a lot of reading about routes and it seems like I need something like this in routes:
get ':state/:city/:slug', to: 'schools#show'
I tried this to no avail:
resources schools, except: show, param :slug
get ':state/:city/:slug', to: 'schools#show'
I ended up changing my routes file like this:
resources :schools, :only => [:index, :new, :create, :edit]
resources :schools, :only => [:show], path: 'IL/:city/', param: :slug
I then changed the slug script to remove the 'IL/city' bit like this (and ran this rake task again to update the slugs):
def to_slug(string)
string.parameterize.truncate(80, omission: '')
end
slugs = []
School.find_each do |school|
slug = to_slug(school.name)
if slugs.include?(slug)
slug = slug + "-2"
p "Same Name"
end
p slug
slugs << slug
school.slug = slug
school.save
end
and then wherever there was a link_to(school.name, school)
I had to change to look like this:
link_to(school.name, school_path(slug: school.slug, city: school.city.parameterize.truncate(80, omission: ''))
I'm sure there is a better way to do this, but this works for now.