friendly_id 2.2.2 → 2.2.3

Sign up to get free protection for your applications and to get access to all the features.
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