Permalink
Browse files

has_friendly_id => friendly_id, and accept "use" arg to load modules

  • Loading branch information...
1 parent 6db0fca commit 70c8884781f409fc7b94db8fed3ac27b7ae176b7 @norman committed Jul 17, 2011
View
@@ -25,8 +25,9 @@ column with no spaces or special characters, and that is seldom or never
updated. The most common example of this is a user name or login column:
class User < ActiveRecord::Base
+ extend FriendlyId
validates_format_of :login, :with => /\A[a-z0-9]+\z/i
- has_friendly_id :login
+ friendly_id :login
end
@user = User.find "joe" # the old User.find(1) still works, too
@@ -38,7 +39,8 @@ modify the value of the column, and your application should ensure that the valu
is admissible in a URL:
class City < ActiveRecord::Base
- has_friendly_id :name
+ extend FriendlyId
+ friendly_id :name
end
@city.find "Viña del Mar"
@@ -55,8 +57,8 @@ title, which may have spaces, uppercase characters, or other attributes you
wish to modify to make them more suitable for use in URL's.
class Post < ActiveRecord::Base
- include FriendlyId::Slugged
- has_friendly_id :title
+ extend FriendlyId
+ friendly_id :title, :use => :slugged
end
@post = Post.create(:title => "This is the first post!")
@@ -83,16 +85,13 @@ dropped until a stable release of 3.2 is out, or possibly longer.
## Configuration
-FriendlyId is configured in your model using the `has_friendly_id` method. Additional
-features can be activated by including various modules:
+FriendlyId is configured in your model using the `friendly_id` method. Additional
+features can be passing the names of modules into the `:use` option:
class Post < ActiveRecord::Base
- # use slugs
- include FriendlyId::Slugged
- # record slug history
- include FriendlyId::History
+ extend FriendlyId
# use the "title" accessor as the basis of the friendly_id
- has_friendly_id :title
+ friendly_id :title, :use => [:slugged, :history]
end
Read on to learn about the various features that can be configured. For the
@@ -121,10 +120,9 @@ FriendlyId can use either a column or a method to generate the slug text for
your model:
class City < ActiveRecord::Base
-
+ extend FriendlyId
belongs_to :country
- include FriendlyId::Slugged
- has_friendly_id :name_and_country
+ friendly_id :name_and_country, :use => :slugged
def name_and_country
#{name} #{country.name}
@@ -148,9 +146,8 @@ you can override the `normalize_friendly_id` method in your model class in
order to fine-tune the output:
class City < ActiveRecord::Base
-
- include FriendlyId::Slugged
- has_friendly_id :whatever
+ extend FriendlyId
+ friendly_id :whatever, :use => :slugged
def normalize_friendly_id(text)
my_text_modifier_method(text)
@@ -186,9 +183,8 @@ FriendlyId can maintain a history of your record's older slugs, so if your
record's friendly_id changes, your URL's won't break.
class Post < ActiveRecord::Base
- include FriendlyId::Slugged
- include FriendlyId::History
- has_friendly_id :title
+ extend FriendlyId
+ friendly_id :title, :use => :history
end
class PostsController < ApplicationController
@@ -230,10 +226,9 @@ the rest of the slug. This is important to enable having slugs like:
/cars/peugeot-206--2
You can configure the separator string used by your model by setting the
-`:sequence_separator` option in `has_friendly_id`:
+`:sequence_separator` option in `friendly_id`:
- include FriendlyId::Slugged
- has_friendly_id :title, :sequence_separator => ":"
+ friendly_id :title, :use => :slugged, :sequence_separator => ":"
You can also override the default used in
{FriendlyId::Configuration::DEFAULTS} to set the value for any model using
@@ -259,16 +254,15 @@ names unique for each city, so that the second "Joe's Diner" can also have the
slug "joes-diner", as long as it's located in a different city:
class Restaurant < ActiveRecord::Base
+ extend FriendlyId
belongs_to :city
- include FriendlyId::Slugged
- include FriendlyId::Scoped
- has_friendly_id :name, :scope => :city
+ friendly_id :name, :use => :scoped, :scope => :city
end
class City < ActiveRecord::Base
+ extend FriendlyId
has_many :restaurants
- include FriendlyId::Slugged
- has_friendly_id :name
+ friendly_id :name, :use => :slugged
end
City.find("seattle").restaurants.find("joes-diner")
View
@@ -58,8 +58,8 @@ FriendlyId is compatible with Active Record **3.0** and **3.1**.
# edit app/models/user.rb
class User < ActiveRecord::Base
- include FriendlyId::Slugged
- has_friendly_id :name
+ extend FriendlyId
+ friendly_id :name, :use => :slugged
end
User.create! :name => "Joe Schmoe"
View
@@ -18,13 +18,13 @@ def rand
class Journalist < ActiveRecord::Base
extend FriendlyId
include FriendlyId::Slugged
- has_friendly_id :name
+ friendly_id :name
end
class Manual < ActiveRecord::Base
extend FriendlyId
include FriendlyId::History
- has_friendly_id :name
+ friendly_id :name
end
BOOKS = []
View
@@ -20,5 +20,4 @@ def self.extended(base)
end
ActiveRecord::Relation.send :include, FriendlyId::FinderMethods
end
-
end
@@ -2,8 +2,11 @@ module FriendlyId
# Class methods that will be added to ActiveRecord::Base.
module Base
- def has_friendly_id(*args)
- @friendly_id_config.set args.extract_options!.merge(:base => args.shift)
+ def friendly_id(*args)
+ base = args.shift
+ options = args.extract_options!
+ @friendly_id_config.use options.delete :use
+ @friendly_id_config.set options.merge :base => base
before_save do |record|
record.instance_eval {@current_friendly_id = friendly_id}
end
@@ -1,5 +1,5 @@
module FriendlyId
- # The configuration paramters passed to +has_friendly_id+ will be stored in
+ # The configuration paramters passed to +friendly_id+ will be stored in
# this object.
class Configuration
attr_reader :base
@@ -31,6 +31,12 @@ def query_field
base
end
+ def use(*modules)
+ modules.compact.each do |name|
+ klass.send :include, FriendlyId.const_get(name.to_s.classify)
+ end
+ end
+
def set(values)
values and values.each {|name, value| self.send "#{name}=", value}
end
@@ -5,7 +5,7 @@ module FinderMethods
protected
def find_one(id)
- return super if !@klass.respond_to?(:has_friendly_id) || id.unfriendly_id?
+ return super if !@klass.respond_to?(:friendly_id) || id.unfriendly_id?
where(@klass.friendly_id_config.query_field => id).first or super
end
end
@@ -3,12 +3,13 @@
module FriendlyId
module History
- def self.included(base)
- base.class_eval do
- include Slugged unless include? Slugged
- extend Finder
+ def self.included(klass)
+ klass.instance_eval do
+ include Slugged unless self < Slugged
has_many :friendly_id_slugs, :as => :sluggable, :dependent => :destroy
before_save :build_friendly_id_slug, :if => lambda {|r| r.slug_sequencer.slug_changed?}
+ scope :with_friendly_id, lambda {|id| includes(:friendly_id_slugs).where("friendly_id_slugs.slug = ?", id)}
+ extend Finder
end
end
@@ -21,7 +22,7 @@ def build_friendly_id_slug
module Finder
def find_by_friendly_id(*args)
- where("friendly_id_slugs.slug = ?", args.shift).includes(:friendly_id_slugs).first(*args)
+ with_friendly_id(args.shift).first(*args)
end
end
end
@@ -12,7 +12,7 @@ module FriendlyId
# class Restaurant < ActiveRecord::Base
# belongs_to :city
# include FriendlyId::Scoped
- # has_friendly_id :name, :scope => :city
+ # friendly_id :name, :scope => :city
# end
module Scoped
def self.included(klass)
@@ -28,7 +28,7 @@ module Configuration
# Gets the scope column.
#
- # Checks to see if the +:scope+ option passed to {#has_friendly_id}
+ # Checks to see if the +:scope+ option passed to {#friendly_id}
# refers to a relation, and if so, returns the realtion's foreign key.
# Otherwise it assumes the option value was the name of column and returns
# it cast to a String.
@@ -48,7 +48,6 @@ def conflict
@conflict
end
- # @NOTE AR-specific code here
def conflicts
pkey = sluggable.class.primary_key
value = sluggable.send pkey
View
@@ -3,7 +3,7 @@
Author, Book = 2.times.map do
Class.new(ActiveRecord::Base) do
extend FriendlyId
- has_friendly_id :name
+ friendly_id :name
end
end
@@ -17,11 +17,11 @@ def klass
end
test "models don't use friendly_id by default" do
- assert !Class.new(ActiveRecord::Base).respond_to?(:has_friendly_id)
+ assert !Class.new(ActiveRecord::Base).respond_to?(:friendly_id)
end
test "model classes should have a friendly id config" do
- assert klass.has_friendly_id(:name).friendly_id_config
+ assert klass.friendly_id(:name).friendly_id_config
end
test "should reserve 'new' and 'edit' by default" do
@@ -2,8 +2,7 @@
class Manual < ActiveRecord::Base
extend FriendlyId
- include FriendlyId::History
- has_friendly_id :name
+ friendly_id :name, :use => :history
end
class HistoryTest < MiniTest::Unit::TestCase
View
@@ -2,15 +2,13 @@
class Novelist < ActiveRecord::Base
extend FriendlyId
- include FriendlyId::Slugged
- has_friendly_id :name
+ friendly_id :name, :use => :slugged
end
class Novel < ActiveRecord::Base
extend FriendlyId
- include FriendlyId::Scoped
belongs_to :novelist
- has_friendly_id :name, :scope => :novelist
+ friendly_id :name, :use => :scoped, :scope => :novelist
end
class ScopedTest < MiniTest::Unit::TestCase
@@ -30,7 +28,7 @@ def klass
klass = Class.new(ActiveRecord::Base)
klass.extend FriendlyId
klass.send :include, FriendlyId::Scoped
- klass.has_friendly_id :empty, :scope => :dummy
+ klass.friendly_id :empty, :scope => :dummy
assert_equal "dummy", klass.friendly_id_config.scope_column
end
@@ -3,8 +3,7 @@
Journalist, Article = 2.times.map do
Class.new(ActiveRecord::Base) do
extend FriendlyId
- include FriendlyId::Slugged
- has_friendly_id :name
+ friendly_id :name, :use => :slugged
end
end
@@ -55,8 +54,7 @@ class SlugSequencerTest < MiniTest::Unit::TestCase
klass = Class.new(ActiveRecord::Base)
klass.table_name = "journalists"
klass.extend FriendlyId
- klass.send :include, FriendlyId::Slugged
- klass.has_friendly_id :name, :slug_column => "strange name"
+ klass.friendly_id :name, :use => :slugged, :slug_column => "strange name"
begin
with_instance_of(klass) {|record| assert klass.find(record.friendly_id)}
rescue ActiveRecord::StatementInvalid
@@ -71,8 +69,7 @@ class SlugSeparatorTest < MiniTest::Unit::TestCase
class Journalist < ActiveRecord::Base
extend FriendlyId
- include FriendlyId::Slugged
- has_friendly_id :name, :sequence_separator => ":"
+ friendly_id :name, :use => :slugged, :sequence_separator => ":"
end
def klass

2 comments on commit 70c8884

@luislavena

Nice! has_ and fu need to die! :-P

@norman
Owner
norman commented on 70c8884 Jul 18, 2011

Glad to have your vote in favor. :)

I debated this with myself for hours yesterday. I don't like to break compatibility "just because" but I think here it's justified.

Please sign in to comment.