friendly_id 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,11 @@
1
+ == 2.2.3 2009-11-12
2
+
3
+ * 4 minor enhancements:
4
+ * Fixed some issues with gem load order under 1.8.x (closes GH Issue #20)
5
+ * Made sure friendly_id generator makes a lib/tasks directory (Josh Nichols)
6
+ * Finders now accept instances of ActiveRecord::Base, matching AR's behavior (Josh Nichols)
7
+ * SlugGenerationError now raise when a blank value is passed to strip_diacritics
8
+
1
9
  == 2.2.2 2009-10-26
2
10
 
3
11
  * 1 minor enhancement:
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Norman Clarke and Adrian Mugnolo.
1
+ Copyright (c) 2008 Norman Clarke, Adrian Mugnolo and Emilio Tagua.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
data/README.rdoc CHANGED
@@ -343,10 +343,19 @@ we love pull requests. :-)
343
343
  Please report them on the {Github issue tracker}[http://github.com/norman/friendly_id/issues]
344
344
  for this project.
345
345
 
346
+ If you have a bug to report, please include the following information:
347
+
348
+ * Stack trace and error message.
349
+ * Version information for FriendlyId, Rails and Ruby.
350
+ * Any snippets of relevant model, view or controller code that shows how your are using FriendlyId.
351
+
352
+ If you are able to, it helps even more if you can fork FriendlyId on Github, and
353
+ add a test that reproduces the error you are experiencing.
354
+
346
355
  == Credits:
347
356
 
348
- FriendlyId was created by {Norman Clarke}[mailto:norman@randomba.org],
349
- {Adrian Mugnolo}[mailto:adrian@randomba.org], and {Emilio Tagua}[mailto:miloops@gmail.com].
357
+ FriendlyId was created by {Norman Clarke}[mailto:norman@njclarke.com],
358
+ {Adrian Mugnolo}[mailto:adrian@mugnolo.com], and {Emilio Tagua}[mailto:miloops@gmail.com].
350
359
 
351
360
  We are grateful for many contributions from the Ruby and Rails community, in
352
361
  particular from the following people:
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ Hoe.spec "friendly_id" do
9
9
  self.author = ['Norman Clarke', 'Adrian Mugnolo', 'Emilio Tagua']
10
10
  self.email = ['norman@njclarke.com', 'adrian@mugnolo.com', 'miloops@gmail.com']
11
11
  self.summary = "A comprehensive slugging and pretty-URL plugin for ActiveRecord."
12
- self.description = 'A comprehensive slugging and pretty-URL plugin for ActiveRecord.'
12
+ self.description = 'A comprehensive slugging and pretty-URL plugin for Rails apps using ActiveRecord.'
13
13
  self.url = 'http://friendly-id.rubyforge.org/'
14
14
  self.test_globs = ['test/**/*_test.rb']
15
15
  self.extra_deps << ['activerecord', '>= 2.2.3']
@@ -17,7 +17,22 @@ Hoe.spec "friendly_id" do
17
17
  self.extra_dev_deps << ['newgem', ">= #{::Newgem::VERSION}"]
18
18
  self.extra_dev_deps << ['sqlite3-ruby']
19
19
  self.remote_rdoc_dir = ""
20
+ self.readme_file = "README.rdoc"
20
21
  self.extra_rdoc_files = ["README.rdoc"]
22
+ self.post_install_message = <<-EOM
23
+
24
+ ***********************************************************
25
+
26
+ If you are upgrading friendly_id, please run
27
+
28
+ ./script generate friendly_id --skip-migration
29
+
30
+ in your Rails application to ensure that you have the
31
+ latest friendly_id Rake tasks.
32
+
33
+ ***********************************************************
34
+
35
+ EOM
21
36
  end
22
37
 
23
38
  require 'newgem/tasks'
@@ -1,12 +1,28 @@
1
1
  class FriendlyIdGenerator < Rails::Generator::Base
2
+
2
3
  def manifest
3
4
  record do |m|
4
5
  unless options[:skip_migration]
5
- m.migration_template(
6
- 'create_slugs.rb', 'db/migrate', :migration_file_name => 'create_slugs'
7
- )
6
+ m.migration_template('create_slugs.rb', 'db/migrate', :migration_file_name => 'create_slugs')
7
+ end
8
+ unless options[:skip_tasks]
9
+ m.directory "lib/tasks"
8
10
  m.file "/../../../lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rake"
9
11
  end
10
12
  end
11
13
  end
12
- end
14
+
15
+ protected
16
+
17
+ def add_options!(opt)
18
+ opt.separator ''
19
+ opt.separator 'Options:'
20
+ opt.on("--skip-migration", "Don't generate a migration for the slugs table") do |value|
21
+ options[:skip_migration] = value
22
+ end
23
+ opt.on("--skip-tasks", "Don't add friendly_id Rake tasks to lib/tasks") do |value|
24
+ options[:skip_tasks] = value
25
+ end
26
+ end
27
+
28
+ end
data/init.rb CHANGED
@@ -1,3 +1 @@
1
- # encoding: utf-8
2
-
3
- require 'friendly_id'
1
+ require "friendly_id"
data/lib/friendly_id.rb CHANGED
@@ -1,115 +1,75 @@
1
- # encoding: utf-8
1
+ require "friendly_id/helpers"
2
+ require "friendly_id/slug"
3
+ require "friendly_id/sluggable_class_methods"
4
+ require "friendly_id/sluggable_instance_methods"
5
+ require "friendly_id/non_sluggable_class_methods"
6
+ require "friendly_id/non_sluggable_instance_methods"
2
7
 
3
- require 'friendly_id/helpers'
4
- require 'friendly_id/slug'
5
-
6
- # FriendlyId is a comprehensize Rails plugin/gem for slugging and permalinks.
8
+ # FriendlyId is a comprehensive Ruby library for slugging and permalinks with
9
+ # ActiveRecord.
7
10
  module FriendlyId
8
11
 
9
12
  # Default options for has_friendly_id.
10
- DEFAULT_FRIENDLY_ID_OPTIONS = {
11
- :max_length => 255,
12
- :method => nil,
13
- :reserved => ["new", "index"],
14
- :reserved_message => 'can not be "%s"',
15
- :cache_column => nil,
16
- :scope => nil,
17
- :strip_diacritics => false,
18
- :strip_non_ascii => false,
19
- :use_slug => false }.freeze
13
+ DEFAULT_OPTIONS = {
14
+ :max_length => 255,
15
+ :reserved => ["new", "index"],
16
+ :reserved_message => 'can not be "%s"'
17
+ }.freeze
20
18
 
21
- # Valid keys for has_friendly_id options.
22
- VALID_FRIENDLY_ID_KEYS = [
23
- :max_length,
24
- :reserved,
25
- :reserved_message,
19
+ # The names of all valid configuration options.
20
+ VALID_OPTIONS = (DEFAULT_OPTIONS.keys + [
26
21
  :cache_column,
27
22
  :scope,
28
23
  :strip_diacritics,
29
- :strip_non_ascii,
30
- :use_slug ].freeze
24
+ :stip_non_ascii,
25
+ :use_slug
26
+ ]).freeze
31
27
 
32
28
  # This error is raised when it's not possible to generate a unique slug.
33
29
  class SlugGenerationError < StandardError ; end
34
30
 
35
- module ClassMethods
36
-
37
- # Set up an ActiveRecord model to use a friendly_id.
38
- #
39
- # The column argument can be one of your model's columns, or a method
40
- # you use to generate the slug.
41
- #
42
- # Options:
43
- # * <tt>:use_slug</tt> - Defaults to false. Use slugs when you want to use a non-unique text field for friendly ids.
44
- # * <tt>:max_length</tt> - Defaults to 255. The maximum allowed length for a slug.
45
- # * <tt>:cache_column</tt> - Defaults to nil. Use this column as a cache for generating to_param (experimental) Note that if you use this option, any calls to +attr_accessible+ must be made BEFORE any calls to has_friendly_id in your class.
46
- # * <tt>:strip_diacritics</tt> - Defaults to false. If true, it will remove accents, umlauts, etc. from western characters.
47
- # * <tt>:strip_non_ascii</tt> - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
48
- # * <tt>:reserved</tt> - Array of words that are reserved and can't be used as friendly_id's. For sluggable models, if such a word is used, it will raise a FriendlyId::SlugGenerationError. Defaults to ["new", "index"].
49
- # * <tt>:reserved_message</tt> - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '"%s" is reserved'.
50
- #
51
- # You can also optionally pass a block if you want to use your own custom
52
- # slugnormalization routines rather than the default ones that come with
53
- # friendly_id:
54
- #
55
- # require 'stringex'
56
- # class Post < ActiveRecord::Base
57
- # has_friendly_id :title, :use_slug => true do |text|
58
- # # Use stringex to generate the friendly_id rather than the baked-in methods
59
- # text.to_url
60
- # end
61
- # end
62
- def has_friendly_id(column, options = {}, &block)
63
- options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
64
- unless options.has_key?(:cache_column)
65
- if columns.any? { |c| c.name == 'cached_slug' }
66
- options[:use_slug] = true
67
- options[:cache_column] = :cached_slug
68
- end
69
- end
70
- options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column => column)
71
- write_inheritable_attribute :friendly_id_options, options
72
- class_inheritable_accessor :friendly_id_options
73
- class_inheritable_reader :slug_normalizer_block
74
-
75
- if options[:use_slug]
76
- has_many :slugs, :order => 'id DESC', :as => :sluggable, :dependent => :destroy
77
- require 'friendly_id/sluggable_class_methods'
78
- require 'friendly_id/sluggable_instance_methods'
79
- extend SluggableClassMethods
80
- include SluggableInstanceMethods
81
- before_save :set_slug
82
- after_save :set_slug_cache
83
- if block_given?
84
- write_inheritable_attribute :slug_normalizer_block, block
85
- end
86
- if options[:cache_column]
87
- # only protect the column if the class is not already using attributes_accessible
88
- attr_protected options[:cache_column].to_sym unless accessible_attributes
89
- end
90
- else
91
- require 'friendly_id/non_sluggable_class_methods'
92
- require 'friendly_id/non_sluggable_instance_methods'
93
- extend NonSluggableClassMethods
94
- include NonSluggableInstanceMethods
95
- validate :validate_friendly_id
96
- end
97
- end
98
-
99
- end
100
-
101
- class << self
102
-
103
- # Load FriendlyId if the gem is included in a Rails app.
104
- def enable
105
- return if ActiveRecord::Base.methods.include? 'has_friendly_id'
106
- ActiveRecord::Base.class_eval { extend FriendlyId::ClassMethods }
31
+ # Set up an ActiveRecord model to use a friendly_id.
32
+ #
33
+ # The column argument can be one of your model's columns, or a method
34
+ # you use to generate the slug.
35
+ #
36
+ # Options:
37
+ # * <tt>:use_slug</tt> - Defaults to nil. Use slugs when you want to use a non-unique text field for friendly ids.
38
+ # * <tt>:max_length</tt> - Defaults to 255. The maximum allowed length for a slug.
39
+ # * <tt>:cache_column</tt> - Defaults to nil. Use this column as a cache for generating to_param (experimental) Note that if you use this option, any calls to +attr_accessible+ must be made BEFORE any calls to has_friendly_id in your class.
40
+ # * <tt>:strip_diacritics</tt> - Defaults to nil. If true, it will remove accents, umlauts, etc. from western characters.
41
+ # * <tt>:strip_non_ascii</tt> - Defaults to nil. If true, it will remove all non-ASCII characters.
42
+ # * <tt>:reserved</tt> - Array of words that are reserved and can't be used as friendly_id's. For sluggable models, if such a word is used, it will raise a FriendlyId::SlugGenerationError. Defaults to ["new", "index"].
43
+ # * <tt>:reserved_message</tt> - The validation message that will be shown when a reserved word is used as a frindly_id. Defaults to '"%s" is reserved'.
44
+ #
45
+ # You can also optionally pass a block if you want to use your own custom
46
+ # slug normalization routines rather than the default ones that come with
47
+ # friendly_id:
48
+ #
49
+ # require "stringex"
50
+ # class Post < ActiveRecord::Base
51
+ # has_friendly_id :title, :use_slug => true do |text|
52
+ # # Use stringex to generate the friendly_id rather than the baked-in methods
53
+ # text.to_url
54
+ # end
55
+ # end
56
+ def has_friendly_id(method, options = {}, &block)
57
+ options.assert_valid_keys VALID_OPTIONS
58
+ options = DEFAULT_OPTIONS.merge(options).merge(:method => method)
59
+ write_inheritable_attribute :friendly_id_options, options
60
+ class_inheritable_accessor :friendly_id_options
61
+ class_inheritable_reader :slug_normalizer_block
62
+ write_inheritable_attribute(:slug_normalizer_block, block) if block_given?
63
+ if friendly_id_options[:use_slug]
64
+ extend SluggableClassMethods
65
+ include SluggableInstanceMethods
66
+ else
67
+ extend NonSluggableClassMethods
68
+ include NonSluggableInstanceMethods
107
69
  end
108
-
109
70
  end
110
-
111
71
  end
112
72
 
113
- if defined?(ActiveRecord)
114
- FriendlyId::enable
73
+ class ActiveRecord::Base
74
+ extend FriendlyId
115
75
  end
@@ -1,7 +1,5 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId
4
-
2
+
5
3
  module Helpers
6
4
  # Calculate expected result size for find_some_with_friendly (taken from
7
5
  # active_record/base.rb)
@@ -11,5 +9,4 @@ module FriendlyId
11
9
  size
12
10
  end
13
11
  end
14
-
15
- end
12
+ end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId::NonSluggableClassMethods
4
2
 
5
3
  include FriendlyId::Helpers
@@ -7,7 +5,7 @@ module FriendlyId::NonSluggableClassMethods
7
5
  protected
8
6
 
9
7
  def find_one(id, options) #:nodoc:#
10
- if id.is_a?(String) && result = send("find_by_#{ friendly_id_options[:column] }", id, options)
8
+ if id.is_a?(String) && result = send("find_by_#{ friendly_id_options[:method] }", id, options)
11
9
  result.send(:found_using_friendly_id=, true)
12
10
  else
13
11
  result = super id, options
@@ -18,7 +16,7 @@ module FriendlyId::NonSluggableClassMethods
18
16
  def find_some(ids_and_names, options) #:nodoc:#
19
17
 
20
18
  results = with_scope :find => options do
21
- find :all, :conditions => ["#{quoted_table_name}.#{primary_key} IN (?) OR #{friendly_id_options[:column].to_s} IN (?)",
19
+ find :all, :conditions => ["#{quoted_table_name}.#{primary_key} IN (?) OR #{friendly_id_options[:method].to_s} IN (?)",
22
20
  ids_and_names, ids_and_names]
23
21
  end
24
22
 
@@ -32,4 +30,4 @@ module FriendlyId::NonSluggableClassMethods
32
30
  results
33
31
 
34
32
  end
35
- end
33
+ end
@@ -1,7 +1,9 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId::NonSluggableInstanceMethods
4
2
 
3
+ def self.included(base)
4
+ base.validate :validate_friendly_id
5
+ end
6
+
5
7
  attr :found_using_friendly_id
6
8
 
7
9
  # Was the record found using one of its friendly ids?
@@ -17,7 +19,7 @@ module FriendlyId::NonSluggableInstanceMethods
17
19
 
18
20
  # Returns the friendly_id.
19
21
  def friendly_id
20
- send friendly_id_options[:column]
22
+ send friendly_id_options[:method]
21
23
  end
22
24
  alias best_id friendly_id
23
25
 
@@ -27,10 +29,10 @@ module FriendlyId::NonSluggableInstanceMethods
27
29
  end
28
30
 
29
31
  private
30
-
32
+
31
33
  def validate_friendly_id
32
34
  if self.class.friendly_id_options[:reserved].include? friendly_id
33
- self.errors.add(self.class.friendly_id_options[:column],
35
+ self.errors.add(self.class.friendly_id_options[:method],
34
36
  self.class.friendly_id_options[:reserved_message] % friendly_id)
35
37
  return false
36
38
  end
@@ -1,5 +1,3 @@
1
- #encoding: utf-8
2
-
3
1
  # A Slug is a unique, human-friendly identifier for an ActiveRecord.
4
2
  class Slug < ActiveRecord::Base
5
3
 
@@ -49,7 +47,7 @@ class Slug < ActiveRecord::Base
49
47
  # Remove diacritics (accents, umlauts, etc.) from the string. Borrowed
50
48
  # from "The Ruby Way."
51
49
  def strip_diacritics(string)
52
- a = ActiveSupport::Multibyte.proxy_class.new(string).normalize(:kd) || ""
50
+ a = ActiveSupport::Multibyte.proxy_class.new(string || "").normalize(:kd)
53
51
  a.unpack('U*').inject([]) { |a, u|
54
52
  if ASCII_APPROXIMATIONS[u]
55
53
  a += ASCII_APPROXIMATIONS[u].unpack('U*')
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId::SluggableClassMethods
4
2
 
5
3
  include FriendlyId::Helpers
@@ -8,7 +6,10 @@ module FriendlyId::SluggableClassMethods
8
6
  def find_one(id_or_name, options) #:nodoc:#
9
7
 
10
8
  scope = options.delete(:scope)
11
- return super(id_or_name, options) if id_or_name.is_a?(Integer)
9
+
10
+ if id_or_name.is_a?(Integer) || id_or_name.kind_of?(ActiveRecord::Base)
11
+ return super(id_or_name, options)
12
+ end
12
13
 
13
14
  find_options = {:select => "#{self.table_name}.*"}
14
15
  find_options[:joins] = :slugs unless options[:include] && [*options[:include]].flatten.include?(:slugs)
@@ -1,7 +1,20 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId::SluggableInstanceMethods
4
2
 
3
+ def self.included(base)
4
+ base.has_many :slugs, :order => 'id DESC', :as => :sluggable, :dependent => :destroy
5
+ base.before_save :set_slug
6
+ base.after_save :set_slug_cache
7
+ unless base.friendly_id_options[:cache_column]
8
+ if base.columns.any? { |c| c.name == 'cached_slug' }
9
+ base.friendly_id_options[:cache_column] = :cached_slug
10
+ end
11
+ end
12
+ # only protect the column if the class is not already using attributes_accessible
13
+ if base.friendly_id_options[:cache_column] && !base.accessible_attributes
14
+ base.attr_protected base.friendly_id_options[:cache_column].to_sym
15
+ end
16
+ end
17
+
5
18
  NUM_CHARS_RESERVED_FOR_FRIENDLY_ID_EXTENSION = 2
6
19
 
7
20
  attr :finder_slug
@@ -68,7 +81,7 @@ module FriendlyId::SluggableInstanceMethods
68
81
 
69
82
  # Get the processed string used as the basis of the friendly id.
70
83
  def slug_text
71
- base = send friendly_id_options[:column]
84
+ base = send friendly_id_options[:method]
72
85
  if self.slug_normalizer_block
73
86
  base = self.slug_normalizer_block.call(base)
74
87
  else
@@ -5,8 +5,7 @@ module FriendlyId
5
5
  def make_slugs(klass, options = {})
6
6
  klass = parse_class_name(klass)
7
7
  validate_uses_slugs(klass)
8
- options = {:limit => 100, :include => :slugs, :order => "#{klass.table_name}.id ASC",
9
- :conditions => "slugs.id IS NULL"}.merge(options)
8
+ options = {:limit => 100, :include => :slugs, :conditions => "slugs.id IS NULL"}.merge(options)
10
9
  while records = klass.find(:all, options) do
11
10
  break if records.size == 0
12
11
  records.each do |r|
@@ -1,10 +1,8 @@
1
- # encoding: utf-8
2
-
3
1
  module FriendlyId #:nodoc:
4
2
  module Version #:nodoc:
5
3
  MAJOR = 2
6
4
  MINOR = 2
7
- TINY = 2
5
+ TINY = 3
8
6
  STRING = [MAJOR, MINOR, TINY].join('.')
9
7
  end
10
8
  end
@@ -1,5 +1,3 @@
1
- require "friendly_id/tasks"
2
-
3
1
  namespace :friendly_id do
4
2
  desc "Make slugs for a model."
5
3
  task :make_slugs => :environment do
@@ -36,9 +36,9 @@ class CachedSlugModelTest < Test::Unit::TestCase
36
36
  end
37
37
 
38
38
  should "cache the incremented sequence for duplicate slug names" do
39
- @paris2 = City.create!(:name => "Paris")
40
- assert_equal 2, @paris2.slug.sequence
41
- assert_equal "paris--2", @paris2.my_slug
39
+ paris2 = City.create!(:name => "Paris")
40
+ assert_equal 2, paris2.slug.sequence
41
+ assert_equal "paris--2", paris2.my_slug
42
42
  end
43
43
 
44
44
  should "not update the cached slug column if it has not changed" do
@@ -7,7 +7,7 @@ class CustomSlugNormalizerTest < Test::Unit::TestCase
7
7
  context "A slugged model using a custom slug generator" do
8
8
 
9
9
  setup do
10
- Thing.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :name, :use_slug => true)
10
+ Thing.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :name, :use_slug => true)
11
11
  end
12
12
 
13
13
  teardown do
@@ -16,14 +16,14 @@ class CustomSlugNormalizerTest < Test::Unit::TestCase
16
16
  end
17
17
 
18
18
  should "invoke the block code" do
19
- @thing = Thing.create!(:name => "test")
20
- assert_equal "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", @thing.friendly_id
19
+ thing = Thing.create!(:name => "test")
20
+ assert_equal "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", thing.friendly_id
21
21
  end
22
22
 
23
23
  should "respect the max_length option" do
24
24
  Thing.friendly_id_options = Thing.friendly_id_options.merge(:max_length => 10)
25
- @thing = Thing.create!(:name => "test")
26
- assert_equal "a94a8fe5cc", @thing.friendly_id
25
+ thing = Thing.create!(:name => "test")
26
+ assert_equal "a94a8fe5cc", thing.friendly_id
27
27
  end
28
28
 
29
29
  should "respect the reserved option" do
@@ -1,3 +1,3 @@
1
1
  class District < ActiveRecord::Base
2
- has_friendly_id :name
2
+ has_friendly_id :name, :use_slug => true
3
3
  end
@@ -0,0 +1,4 @@
1
+ class LegacyThing < ActiveRecord::Base
2
+ self.table_name = "legacy_table"
3
+ has_friendly_id :name, :use_slug => true
4
+ end
@@ -37,23 +37,23 @@ class NonSluggedTest < Test::Unit::TestCase
37
37
  end
38
38
 
39
39
  should "indicate if it was found by its friendly id" do
40
- @user = User.find(@user.friendly_id)
41
- assert @user.found_using_friendly_id?
40
+ user = User.find(@user.friendly_id)
41
+ assert user.found_using_friendly_id?
42
42
  end
43
43
 
44
44
  should "indicate if it was found by its numeric id" do
45
- @user = User.find(@user.id)
46
- assert @user.found_using_numeric_id?
45
+ user = User.find(@user.id)
46
+ assert user.found_using_numeric_id?
47
47
  end
48
48
 
49
49
  should "indicate if it has a better id" do
50
- @user = User.find(@user.id)
51
- assert @user.has_better_id?
50
+ user = User.find(@user.id)
51
+ assert user.has_better_id?
52
52
  end
53
53
 
54
54
  should "not validate if the friendly_id text is reserved" do
55
- @user = User.new(:login => "new", :email => "test@example.org")
56
- assert !@user.valid?
55
+ user = User.new(:login => "new", :email => "test@example.org")
56
+ assert !user.valid?
57
57
  end
58
58
 
59
59
  should "have always string for a friendly_id" do
@@ -89,9 +89,9 @@ class NonSluggedTest < Test::Unit::TestCase
89
89
  end
90
90
 
91
91
  should "indicate if the results were found using a friendly_id" do
92
- @users = User.find([@user.id, @user2.friendly_id], :order => "login ASC")
93
- assert @users[0].found_using_friendly_id?
94
- assert @users[1].found_using_numeric_id?
92
+ users = User.find([@user.id, @user2.friendly_id], :order => "login ASC")
93
+ assert users[0].found_using_friendly_id?
94
+ assert users[1].found_using_numeric_id?
95
95
  end
96
96
 
97
97
  end
data/test/schema.rb CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ActiveRecord::Schema.define(:version => 1) do
4
4
 
5
+ create_table "legacy_table", :force => true do |t|
6
+ t.column "name", :string
7
+ end
8
+
5
9
  create_table "books", :force => true do |t|
6
10
  t.column "title", "string"
7
11
  t.column "type", "text"
data/test/slug_test.rb CHANGED
@@ -12,11 +12,11 @@ class SlugTest < Test::Unit::TestCase
12
12
  end
13
13
 
14
14
  should "indicate if it is the most recent slug" do
15
- @post = Post.create!(:title => "test title", :content => "test content")
16
- @post.title = "a new title"
17
- @post.save!
18
- assert @post.slugs.last.is_most_recent?
19
- assert !@post.slugs.first.is_most_recent?
15
+ post = Post.create!(:title => "test title", :content => "test content")
16
+ post.title = "a new title"
17
+ post.save!
18
+ assert post.slugs.last.is_most_recent?
19
+ assert !post.slugs.first.is_most_recent?
20
20
  end
21
21
 
22
22
  end
@@ -7,7 +7,7 @@ class SluggedModelTest < Test::Unit::TestCase
7
7
  context "A slugged model with default FriendlyId options" do
8
8
 
9
9
  setup do
10
- Post.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
10
+ Post.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :title, :use_slug => true)
11
11
  @post = Post.new :title => "Test post", :content => "Test content", :published => true
12
12
  @post.save!
13
13
  end
@@ -17,6 +17,7 @@ class SluggedModelTest < Test::Unit::TestCase
17
17
  Person.delete_all
18
18
  Slug.delete_all
19
19
  Thing.delete_all
20
+ LegacyThing.delete_all
20
21
  end
21
22
 
22
23
  should "have friendly_id options" do
@@ -39,6 +40,10 @@ class SluggedModelTest < Test::Unit::TestCase
39
40
  assert Post.find(@post.id.to_s)
40
41
  end
41
42
 
43
+ should "be findable by its instance" do
44
+ assert Post.find(@post)
45
+ end
46
+
42
47
  should "not be findable by its id if looking for something else" do
43
48
  assert_raises ActiveRecord::RecordNotFound do
44
49
  Post.find("#{@post.id}-i-dont-exists")
@@ -47,7 +52,7 @@ class SluggedModelTest < Test::Unit::TestCase
47
52
 
48
53
  should "generate slug text" do
49
54
  post = Post.new :title => "Test post", :content => "Test content"
50
- assert_not_nil @post.slug_text
55
+ assert_not_nil post.slug_text
51
56
  end
52
57
 
53
58
  should "respect finder conditions" do
@@ -62,12 +67,18 @@ class SluggedModelTest < Test::Unit::TestCase
62
67
  end
63
68
  end
64
69
 
65
- should "raise an error if the friendly_id text is blank" do
70
+ should "raise an error if the friendly_id text is an empty string" do
66
71
  assert_raises(FriendlyId::SlugGenerationError) do
67
72
  Post.create(:title => "")
68
73
  end
69
74
  end
70
75
 
76
+ should "raise an error if the friendly_id text is nil" do
77
+ assert_raises(FriendlyId::SlugGenerationError) do
78
+ Post.create(:title => nil)
79
+ end
80
+ end
81
+
71
82
  should "raise an error if the normalized friendly id becomes blank" do
72
83
  assert_raises(FriendlyId::SlugGenerationError) do
73
84
  post = Post.create!(:title => "-.-")
@@ -105,28 +116,28 @@ class SluggedModelTest < Test::Unit::TestCase
105
116
  end
106
117
 
107
118
  should "not strip diacritics" do
108
- @post = Post.new(:title => "¡Feliz año!")
109
- assert_match(/#{'ñ'}/, @post.slug_text)
119
+ post = Post.new(:title => "¡Feliz año!")
120
+ assert_match(/#{'ñ'}/, post.slug_text)
110
121
  end
111
122
 
112
123
  should "not convert to ASCII" do
113
- @post = Post.new(:title => "katakana: ゲコゴサザシジ")
114
- assert_equal "katakana-ゲコゴサザシジ", @post.slug_text
124
+ post = Post.new(:title => "katakana: ゲコゴサザシジ")
125
+ assert_equal "katakana-ゲコゴサザシジ", post.slug_text
115
126
  end
116
127
 
117
128
  should "allow the same friendly_id across models" do
118
- @person = Person.create!(:name => @post.title)
119
- assert_equal @person.friendly_id, @post.friendly_id
129
+ person = Person.create!(:name => @post.title)
130
+ assert_equal person.friendly_id, @post.friendly_id
120
131
  end
121
132
 
122
133
  should "truncate slug text longer than the max length" do
123
- @post = Post.new(:title => "a" * (Post.friendly_id_options[:max_length] + 1))
124
- assert_equal @post.slug_text.length, Post.friendly_id_options[:max_length]
134
+ post = Post.new(:title => "a" * (Post.friendly_id_options[:max_length] + 1))
135
+ assert_equal post.slug_text.length, Post.friendly_id_options[:max_length]
125
136
  end
126
137
 
127
138
  should "truncate slug in 'right way' when slug is unicode" do
128
- @post = Post.new(:title => "ё" * 100 + 'ю' *(Post.friendly_id_options[:max_length] - 100 + 1))
129
- assert_equal @post.slug_text.mb_chars[-1], 'ю'
139
+ post = Post.new(:title => "ё" * 100 + 'ю' *(Post.friendly_id_options[:max_length] - 100 + 1))
140
+ assert_equal post.slug_text.mb_chars[-1], 'ю'
130
141
  end
131
142
 
132
143
  should "be able to reuse an old friendly_id without incrementing the sequence" do
@@ -157,9 +168,22 @@ class SluggedModelTest < Test::Unit::TestCase
157
168
  end
158
169
 
159
170
  should "strip diacritics from Roman alphabet based characters" do
160
- @post = Post.new(:title => "¡Feliz año!")
161
- assert_no_match(/#{'ñ'}/, @post.slug_text)
171
+ post = Post.new(:title => "¡Feliz año!")
172
+ assert_no_match(/#{'ñ'}/, post.slug_text)
173
+ end
174
+
175
+ should "raise an error if the friendly_id text is an empty string" do
176
+ assert_raises(FriendlyId::SlugGenerationError) do
177
+ Post.create(:title => "")
178
+ end
179
+ end
180
+
181
+ should "raise an error if the friendly_id text is nil" do
182
+ assert_raises(FriendlyId::SlugGenerationError) do
183
+ Post.create(:title => nil)
184
+ end
162
185
  end
186
+
163
187
  end
164
188
 
165
189
  context "and configured to convert to ASCII" do
@@ -168,8 +192,17 @@ class SluggedModelTest < Test::Unit::TestCase
168
192
  end
169
193
 
170
194
  should "strip non-ascii characters" do
171
- @post = Post.new(:title => "katakana: ゲコゴサザシジ")
172
- assert_equal "katakana", @post.slug_text
195
+ post = Post.new(:title => "katakana: ゲコゴサザシジ")
196
+ assert_equal "katakana", post.slug_text
197
+ end
198
+ end
199
+
200
+ context "that uses a custom table name" do
201
+ should "support normal CRUD operations" do
202
+ assert thing = LegacyThing.create!(:name => "a name")
203
+ thing.name = "a new name"
204
+ assert thing.save!
205
+ assert thing.destroy
173
206
  end
174
207
  end
175
208
 
data/test/sti_test.rb CHANGED
@@ -7,7 +7,7 @@ class STIModelTest < Test::Unit::TestCase
7
7
  context "A slugged model using single table inheritance" do
8
8
 
9
9
  setup do
10
- Novel.friendly_id_options = FriendlyId::DEFAULT_FRIENDLY_ID_OPTIONS.merge(:column => :title, :use_slug => true)
10
+ Novel.friendly_id_options = FriendlyId::DEFAULT_OPTIONS.merge(:method => :title, :use_slug => true)
11
11
  @novel = Novel.new :title => "Test novel"
12
12
  @novel.save!
13
13
  end
data/test/test_helper.rb CHANGED
@@ -35,3 +35,4 @@ require 'models/thing'
35
35
  require 'models/event'
36
36
  require 'models/city'
37
37
  require 'models/district'
38
+ require 'models/legacy_thing'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_id
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.2
4
+ version: 2.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Norman Clarke
@@ -11,7 +11,7 @@ autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
13
 
14
- date: 2009-10-26 00:00:00 -03:00
14
+ date: 2009-11-12 00:00:00 -03:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
@@ -64,7 +64,7 @@ dependencies:
64
64
  - !ruby/object:Gem::Version
65
65
  version: 2.3.3
66
66
  version:
67
- description: A comprehensive slugging and pretty-URL plugin for ActiveRecord.
67
+ description: A comprehensive slugging and pretty-URL plugin for Rails apps using ActiveRecord.
68
68
  email:
69
69
  - norman@njclarke.com
70
70
  - adrian@mugnolo.com
@@ -75,15 +75,12 @@ extensions: []
75
75
 
76
76
  extra_rdoc_files:
77
77
  - History.txt
78
- - Manifest.txt
79
78
  - README.rdoc
80
79
  files:
81
80
  - History.txt
82
81
  - MIT-LICENSE
83
- - Manifest.txt
84
82
  - README.rdoc
85
83
  - Rakefile
86
- - config/website.yml
87
84
  - generators/friendly_id/friendly_id_generator.rb
88
85
  - generators/friendly_id/templates/create_slugs.rb
89
86
  - generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb
@@ -108,6 +105,7 @@ files:
108
105
  - test/models/country.rb
109
106
  - test/models/district.rb
110
107
  - test/models/event.rb
108
+ - test/models/legacy_thing.rb
111
109
  - test/models/novel.rb
112
110
  - test/models/person.rb
113
111
  - test/models/post.rb
@@ -125,10 +123,22 @@ has_rdoc: true
125
123
  homepage: http://friendly-id.rubyforge.org/
126
124
  licenses: []
127
125
 
128
- post_install_message:
126
+ post_install_message: |+
127
+
128
+ ***********************************************************
129
+
130
+ If you are upgrading friendly_id, please run
131
+
132
+ ./script generate friendly_id --skip-migration
133
+
134
+ in your Rails application to ensure that you have the
135
+ latest friendly_id Rake tasks.
136
+
137
+ ***********************************************************
138
+
129
139
  rdoc_options:
130
140
  - --main
131
- - README.txt
141
+ - README.rdoc
132
142
  require_paths:
133
143
  - lib
134
144
  required_ruby_version: !ruby/object:Gem::Requirement
data/Manifest.txt DELETED
@@ -1,43 +0,0 @@
1
- History.txt
2
- MIT-LICENSE
3
- Manifest.txt
4
- README.rdoc
5
- Rakefile
6
- config/website.yml
7
- generators/friendly_id/friendly_id_generator.rb
8
- generators/friendly_id/templates/create_slugs.rb
9
- generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb
10
- generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb
11
- init.rb
12
- lib/friendly_id.rb
13
- lib/friendly_id/helpers.rb
14
- lib/friendly_id/non_sluggable_class_methods.rb
15
- lib/friendly_id/non_sluggable_instance_methods.rb
16
- lib/friendly_id/slug.rb
17
- lib/friendly_id/sluggable_class_methods.rb
18
- lib/friendly_id/sluggable_instance_methods.rb
19
- lib/friendly_id/tasks.rb
20
- lib/friendly_id/version.rb
21
- lib/tasks/friendly_id.rake
22
- lib/tasks/friendly_id.rb
23
- test/cached_slug_test.rb
24
- test/contest.rb
25
- test/custom_slug_normalizer_test.rb
26
- test/models/book.rb
27
- test/models/city.rb
28
- test/models/country.rb
29
- test/models/district.rb
30
- test/models/event.rb
31
- test/models/novel.rb
32
- test/models/person.rb
33
- test/models/post.rb
34
- test/models/thing.rb
35
- test/models/user.rb
36
- test/non_slugged_test.rb
37
- test/schema.rb
38
- test/scoped_model_test.rb
39
- test/slug_test.rb
40
- test/slugged_model_test.rb
41
- test/sti_test.rb
42
- test/tasks_test.rb
43
- test/test_helper.rb
data/config/website.yml DELETED
@@ -1,2 +0,0 @@
1
- host: compay@rubyforge.org
2
- remote_dir: /var/www/gforge-projects/friendly-id