joshweir
joshweir

Reputation: 5617

Can I use Friendly Id on a Rails model without having to create a slug column on the model table?

On Rails 4.2, I would like to use Friendly Id for routing to a specific model, but dont wan't to create a slug column on the model table. I would instead prefer to use an accessor method on the model and dynamically generate the slug. Is this possible? I couldn't find this in the documentation.

Upvotes: 1

Views: 1392

Answers (2)

joshweir
joshweir

Reputation: 5617

As discussed here I went with the following approach for custom routing based on dynamic slug.

I want custom route like this: /foos/the-title-parameterized-1 (where "1" is the id of the Foo object).

Foo model:

#...
attr_accessor :slug
#dynamically generate a slug, the Rails `parameterize` 
#handles transforming of ugly url characters such as 
#unicode or spaces:
def slug
  "#{self.title.parameterize[0..200]}-#{self.id}"
end
def to_param
  slug
end 
#...

routes.rb:

get 'foos/:slug' => 'foos#show', :as => 'foo'

foos_controller.rb:

def show
  @foo = Foo.find params[:slug].split("-").last.to_i
end 

In my show view, I am able to use the default url helper method foo_path.

Upvotes: 0

lorefnon
lorefnon

Reputation: 13105

You can not do this directly using friendly id because of the way it uses the slug to query the database (relevant source).

However it is not difficult to accomplish what you want. What you will need are two methods:

  1. Model#slug method which will give you slug for a specific model
  2. Model.find_by_slug method which will generate the relevant query for a specific slug.

Now in your controllers you can use Model.find_by_slug to get the relevant model from the path params. However implementing this method might be tricky especially if your Model#slug uses a non-reversible slugging implementation like Slugify because it simply get rids of unrecognized characters in text and normalizes multiple things to same character (eg. _ and - to -)

You can use URI::Escape.encode and URI::Escape.decode but you will end up with somewhat ugly slugs.

Upvotes: 2

Related Questions