I would like to create url slugs for tags managed by the acts_as_taggable_on gem. For instance instead of urls like http://myapp.com/tags/5, I would like to have http://myapp.com/tags/my-tag (where 'my tag' is the tag's unique name).
In models that I create myself I usually do this by overriding the model's to_param method, and creating a "slug" field in the model to save the result of the new to_param method. I tried doing this with the Tag model of ActsAsTaggableOn, but it is not working.
I can otherwise override things in the tag.rb class of ActsAsTaggableOn as follows:
# Overwrite tag class
ActsAsTaggableOn::Tag.class_eval do
def name
n = read_attribute(:name).split
n.each {|word| word.capitalize!}.join(" ")
end
end
However, if I try to override the to_param method in that same block with a method definition like:
def to_param
name.parameterize
end
Rails still generates and responds to routes with integer IDs rather than the parameterized name. In fact in the console if I try something like
ActsAsTaggableOn::Tag.find(1).to_param
The integer ID is returned, rather than the result of the overridden to_param method.
I'd rather not fork the gem and customize it if there is any way I can do it with my own application code. Thanks.
To make this work with latest version (Rails 4.x, friendly_id 5.x) here are the steps you should follow:
Create migration to add slug to tags table
You can rename the :slug column - you should specify the column name in the initializer if you change it. Don't forget to run the migration
rake db:migrate
.Create an initializer for ActsAsTaggableOn
When searching for tags you have to use
ActsAsTaggableOn::Tag.friendly.find 'tag-name'
or add:finders
to friendly_id :use call to use find directly on the model. Read more in friendly_id guides.@vitork's code is a good start but doesn't work for newer versions of friendly_id and acts_as_taggable. Here's an updated initializer:
My db column is called permalink, you can use slugged if you prefer. Btw, I'm using the following:
Thanks Vitork for the initial code!
I'm using the friendly_id ( https://github.com/norman/friendly_id ) gem to manage slugs. My method to create slugs for my tags is similar to yours, but a lit bit simpler.
I've just created the initializer act_as_taggable_on.rb with the following code:
And then:
And voilá:
Hope this help...
Actually the answer is much simplier and you dont need to use friendly_id or any other unnecessary extension.
сonfig/initializers/act_as_taggable_on.rb
Add a slug column if you need to, otherwise skip before_save callback.
Then in the view, instead of iterating like
you'll iterate like this
because tag_list gives you only strings, whereas with tags u have real tags instances. And at least in the controller
There is another way.
Create a controller for the tags with single action:
In routes.rb change the generated route to:
In tags_controller.rb add this code:
where
Entry
is a model name.Now you able to get all entries with nice urls like example.com/tags/animals
Usage in views: