The {FriendlyId::Scoped} module allows FriendlyId to generate unique slugs within a scope.
This allows, for example, two restaurants in different cities to have the slug joes-diner:
class Restaurant < ActiveRecord::Base extend FriendlyId belongs_to :city friendly_id :name, :use => :scoped, :scope => :city end class City < ActiveRecord::Base extend FriendlyId has_many :restaurants friendly_id :name, :use => :slugged end City.find("seattle").restaurants.find("joes-diner") City.find("chicago").restaurants.find("joes-diner")
Without :scoped in this case, one of the restaurants would have the slug joes-diner and the other would have joes-diner--2.
The value for the :scope option can be the name of a belongs_to relation, or a column.
Additionally, the :scope option can receive an array of scope values:
class Cuisine < ActiveRecord::Base extend FriendlyId has_many :restaurants friendly_id :name, :use => :slugged end class City < ActiveRecord::Base extend FriendlyId has_many :restaurants friendly_id :name, :use => :slugged end class Restaurant < ActiveRecord::Base extend FriendlyId belongs_to :city friendly_id :name, :use => :scoped, :scope => [:city, :cuisine] end
All supplied values will be used to determine scope.
If you are using scopes your friendly ids may not be unique, so a simple find like
Restaurant.find("joes-diner")
may return the wrong record. In these cases it's best to query through the relation:
@city.restaurants.find("joes-diner")
Alternatively, you could pass the scope value as a query parameter:
Restaurant.find("joes-diner").where(:city_id => @city.id)
Query the slug column directly:
Restaurant.find_all_by_slug("joes-diner")
Recall that FriendlyId is a database-centric library, and does not set up any routes for scoped models. You must do this yourself in your application. Here's an example of one way to set this up:
# in routes.rb resources :cities do resources :restaurants end # in views <%= link_to 'Show', [@city, @restaurant] %> # in controllers @city = City.find(params[:city_id]) @restaurant = @city.restaurants.find(params[:id]) # URLs: http://example.org/cities/seattle/restaurants/joes-diner http://example.org/cities/chicago/restaurants/joes-diner
Sets up behavior and configuration options for FriendlyId's scoped slugs feature.
# File lib/friendly_id/scoped.rb, line 109 def self.included(model_class) model_class.instance_eval do raise "FriendlyId::Scoped is incompatibe with FriendlyId::History" if self < History include Slugged unless self < Slugged friendly_id_config.class.send :include, Configuration friendly_id_config.slug_generator_class.send :include, SlugGenerator end end
Generated with the Darkfish Rdoc Generator 2.