How to create user freindly routes for tagging

I have a model Image:

class Image < ActiveRecord::Base
  attr_accessible :description, :name, :size, :image, :tag_ids

  has_many :taggings, :dependent => :destroy
  has_many :tags, :through => :taggings
end

Then I have my Tag model:

class Tag < ActiveRecord::Base
  attr_accessible :name
  has_many :taggings, :dependent => :destroy
  has_many :images, :through => :taggings

end

My routes.rb is currently:

resources :images do
    get 'confirm_destroy', :on => :member
end
resources :tags

Now let's say I created a few tags "blue", "red" and "yellow" for the images. On some page I want to show a list of tags and then link them to e.g. www.example.com/yellow where all the images tagged as yellow shall be shown. The view (haml) for this tag list is currently:

- @tags.each do |tag|
  = link_to(tag.name, tag)

But it generates a link to www.example.com/tags/2 (with 2 being the tag_id).

How can I create the correct resources in order to link to www.example.com/yellow instead of www.example.com/tags/2. Will the view with "link_to" be the same in this case?

Answers


You won't be able to create a route to www.example.com/yellow because this doesn't reference a specific resource, and subsequently could create conflicts. Imagine if you had a tag called 'images', Rails wouldn't know if the url to www.example.com/images referred to a specific tag, or the images resource.

The best we can do is create a resource which uses the name as the identifier in the URL, such that www.example.com/tags/yellow would show the tag with 'yellow' as its name attribute.

To do this, you need to define the following to_param method in the model for Tag.

class Tag < ActiveRecord::Base
  attr_accessible :name
  has_many :taggings, :dependent => :destroy
  has_many :images, :through => :taggings

    def to_param
        name
    end
end

This will tell Rails to use the name attribute for routing instead of the default id. Your link_to won't need to be updated, however, your Tag controller will need to now find the Tag by name as opposed to ID, like so:

class TagsController < ApplicationController

    def show
        @tag = Tag.find_by_name(params[:id])
    end

    ...

end

You can do this with to_param method in your model or with friendly_id gem. Ryan Bates has perfect screencast about this http://railscasts.com/episodes/314-pretty-urls-with-friendlyid


Need Your Help

How to web resource to all forms?

html dynamics-crm-2011 dynamics-crm crm microsoft-dynamics

I know how to add Web Resource (html/js/image) to particular entity or form like Contacs, Account, even custom entity, or dash board. But problem is we want to show Web Resource on each and every

How can I parse <img src> with a regex?

regex

I need a clever regex to match ... in these: