0

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'
tomb
  • 1,374
  • 1
  • 13
  • 23
  • Use friendly_id gem probably it will help you to get desired routes. – Anand Sep 01 '18 at 17:39
  • 1
    This is probably due to the fact that strings are not marked as html safe by default. You can override the `School#slug` getter and mark it html safe `super.html_safe`, however if your slug contains user provided content you might not want to do that. – 3limin4t0r Sep 03 '18 at 15:32

1 Answers1

0

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.

tomb
  • 1,374
  • 1
  • 13
  • 23