norman-friendly_id 2.0.2 → 2.0.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 +15 -0
- data/Manifest.txt +5 -18
- data/Rakefile +7 -10
- data/friendly_id.gemspec +16 -7
- data/lib/friendly_id/non_sluggable_class_methods.rb +4 -4
- data/lib/friendly_id/non_sluggable_instance_methods.rb +9 -1
- data/lib/friendly_id/slug.rb +9 -12
- data/lib/friendly_id/sluggable_class_methods.rb +12 -1
- data/lib/friendly_id/sluggable_instance_methods.rb +1 -1
- data/lib/friendly_id/version.rb +1 -1
- data/lib/friendly_id.rb +26 -18
- data/test/models/post.rb +3 -0
- data/test/non_slugged_test.rb +71 -60
- data/test/schema.rb +23 -18
- data/test/scoped_model_test.rb +43 -13
- data/test/slug_test.rb +93 -74
- data/test/slugged_model_test.rb +263 -0
- data/test/test_helper.rb +29 -29
- metadata +38 -24
- data/lib/friendly_id/shoulda_macros.rb +0 -36
- data/test/database.yml +0 -3
- data/test/fixtures/countries.yml +0 -4
- data/test/fixtures/people.yml +0 -7
- data/test/fixtures/post.rb +0 -3
- data/test/fixtures/posts.yml +0 -23
- data/test/fixtures/slugs.yml +0 -53
- data/test/fixtures/users.yml +0 -7
- data/test/rails/2.x/app/controllers/application.rb +0 -0
- data/test/rails/2.x/config/boot.rb +0 -109
- data/test/rails/2.x/config/database.yml +0 -3
- data/test/rails/2.x/config/environment.rb +0 -7
- data/test/rails/2.x/config/environments/test.rb +0 -6
- data/test/rails/2.x/config/routes.rb +0 -0
- data/test/sluggable_test.rb +0 -192
- /data/test/{fixtures → models}/country.rb +0 -0
- /data/test/{fixtures → models}/person.rb +0 -0
- /data/test/{fixtures → models}/user.rb +0 -0
data/History.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
== 2.0.3 2009-02-11
|
2
|
+
|
3
|
+
* 1 minor enhancment:
|
4
|
+
* Fixed to_param returning an empty string for non-slugged models with a null friendly_id.
|
5
|
+
|
6
|
+
== 2.0.2 2009-02-09
|
7
|
+
|
8
|
+
* 2 major enhancements:
|
9
|
+
* Made FriendlyId depend only on ActiveRecord. It should now be possible to
|
10
|
+
use FriendlyId with Camping or any other codebase that uses AR.
|
11
|
+
* Overhauled creaky testing setup and switched to Shoulda.
|
12
|
+
|
13
|
+
* 1 minor enhancment:
|
14
|
+
* Made reserved words work for non-slugged models.
|
15
|
+
|
1
16
|
== 2.0.1 2009-01-19
|
2
17
|
|
3
18
|
* 1 minor enhancements:
|
data/Manifest.txt
CHANGED
@@ -14,32 +14,19 @@ lib/friendly_id.rb
|
|
14
14
|
lib/friendly_id/helpers.rb
|
15
15
|
lib/friendly_id/non_sluggable_class_methods.rb
|
16
16
|
lib/friendly_id/non_sluggable_instance_methods.rb
|
17
|
-
lib/friendly_id/shoulda_macros.rb
|
18
17
|
lib/friendly_id/slug.rb
|
19
18
|
lib/friendly_id/sluggable_class_methods.rb
|
20
19
|
lib/friendly_id/sluggable_instance_methods.rb
|
21
20
|
lib/friendly_id/version.rb
|
22
21
|
lib/tasks/friendly_id.rake
|
23
22
|
lib/tasks/friendly_id.rb
|
24
|
-
test/
|
25
|
-
test/
|
26
|
-
test/
|
27
|
-
test/
|
28
|
-
test/fixtures/person.rb
|
29
|
-
test/fixtures/post.rb
|
30
|
-
test/fixtures/posts.yml
|
31
|
-
test/fixtures/slugs.yml
|
32
|
-
test/fixtures/user.rb
|
33
|
-
test/fixtures/users.yml
|
23
|
+
test/models/country.rb
|
24
|
+
test/models/person.rb
|
25
|
+
test/models/post.rb
|
26
|
+
test/models/user.rb
|
34
27
|
test/non_slugged_test.rb
|
35
|
-
test/rails/2.x/app/controllers/application.rb
|
36
|
-
test/rails/2.x/config/boot.rb
|
37
|
-
test/rails/2.x/config/database.yml
|
38
|
-
test/rails/2.x/config/environment.rb
|
39
|
-
test/rails/2.x/config/environments/test.rb
|
40
|
-
test/rails/2.x/config/routes.rb
|
41
28
|
test/schema.rb
|
42
29
|
test/scoped_model_test.rb
|
43
30
|
test/slug_test.rb
|
44
|
-
test/
|
31
|
+
test/slugged_model_test.rb
|
45
32
|
test/test_helper.rb
|
data/Rakefile
CHANGED
@@ -5,18 +5,15 @@ $hoe = Hoe.new("friendly_id", FriendlyId::Version::STRING) do |p|
|
|
5
5
|
p.rubyforge_name = "friendly-id"
|
6
6
|
p.author = ['Norman Clarke', 'Adrian Mugnolo', 'Emilio Tagua']
|
7
7
|
p.email = ['norman@randomba.org', 'adrian@randomba.org', 'miloops@gmail.com']
|
8
|
-
p.summary = "A comprehensive slugging and pretty-URL plugin for
|
9
|
-
p.description = 'A comprehensive slugging and pretty-URL plugin for
|
10
|
-
p.url = 'http://
|
11
|
-
p.need_tar = true
|
12
|
-
p.need_zip = true
|
8
|
+
p.summary = "A comprehensive slugging and pretty-URL plugin for ActiveRecord."
|
9
|
+
p.description = 'A comprehensive slugging and pretty-URL plugin for ActiveRecord.'
|
10
|
+
p.url = 'http://friendly-id.rubyforge.org/'
|
13
11
|
p.test_globs = ['test/**/*_test.rb']
|
14
12
|
p.extra_deps << ['unicode', '>= 0.1']
|
15
|
-
p.
|
16
|
-
|
17
|
-
]
|
18
|
-
p.
|
19
|
-
changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
13
|
+
p.extra_deps << ['activerecord', '>= 2.0.0']
|
14
|
+
p.extra_dev_deps << ['newgem', ">= #{::Newgem::VERSION}"]
|
15
|
+
p.extra_dev_deps << ['Shoulda', ">= 1.2.0"]
|
16
|
+
p.extra_dev_deps << ['sqlite3-ruby']
|
20
17
|
p.remote_rdoc_dir = ""
|
21
18
|
end
|
22
19
|
|
data/friendly_id.gemspec
CHANGED
@@ -2,23 +2,23 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{friendly_id}
|
5
|
-
s.version = "2.0.
|
5
|
+
s.version = "2.0.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Norman Clarke", "Adrian Mugnolo", "Emilio Tagua"]
|
9
|
-
s.date = %q{2009-02-
|
10
|
-
s.description = %q{A comprehensive slugging and pretty-URL plugin for
|
9
|
+
s.date = %q{2009-02-11}
|
10
|
+
s.description = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
|
11
11
|
s.email = ["norman@randomba.org", "adrian@randomba.org", "miloops@gmail.com"]
|
12
12
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.rdoc"]
|
13
|
-
s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/
|
13
|
+
s.files = ["History.txt", "MIT-LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "config/website.yml", "friendly_id.gemspec", "generators/friendly_id/friendly_id_generator.rb", "generators/friendly_id/templates/create_slugs.rb", "generators/friendly_id_20_upgrade/friendly_id_20_upgrade_generator.rb", "generators/friendly_id_20_upgrade/templates/upgrade_friendly_id_to_20.rb", "init.rb", "lib/friendly_id.rb", "lib/friendly_id/helpers.rb", "lib/friendly_id/non_sluggable_class_methods.rb", "lib/friendly_id/non_sluggable_instance_methods.rb", "lib/friendly_id/slug.rb", "lib/friendly_id/sluggable_class_methods.rb", "lib/friendly_id/sluggable_instance_methods.rb", "lib/friendly_id/version.rb", "lib/tasks/friendly_id.rake", "lib/tasks/friendly_id.rb", "test/models/country.rb", "test/models/person.rb", "test/models/post.rb", "test/models/user.rb", "test/non_slugged_test.rb", "test/schema.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb", "test/test_helper.rb"]
|
14
14
|
s.has_rdoc = true
|
15
|
-
s.homepage = %q{http://
|
15
|
+
s.homepage = %q{http://friendly-id.rubyforge.org/}
|
16
16
|
s.rdoc_options = ["--main", "README.rdoc"]
|
17
17
|
s.require_paths = ["lib"]
|
18
18
|
s.rubyforge_project = %q{friendly-id}
|
19
19
|
s.rubygems_version = %q{1.3.1}
|
20
|
-
s.summary = %q{A comprehensive slugging and pretty-URL plugin for
|
21
|
-
s.test_files = ["test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/
|
20
|
+
s.summary = %q{A comprehensive slugging and pretty-URL plugin for ActiveRecord.}
|
21
|
+
s.test_files = ["test/non_slugged_test.rb", "test/scoped_model_test.rb", "test/slug_test.rb", "test/slugged_model_test.rb"]
|
22
22
|
|
23
23
|
if s.respond_to? :specification_version then
|
24
24
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
@@ -26,16 +26,25 @@ Gem::Specification.new do |s|
|
|
26
26
|
|
27
27
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
28
|
s.add_runtime_dependency(%q<unicode>, [">= 0.1"])
|
29
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 2.0.0"])
|
29
30
|
s.add_development_dependency(%q<newgem>, [">= 1.2.3"])
|
31
|
+
s.add_development_dependency(%q<Shoulda>, [">= 1.2.0"])
|
32
|
+
s.add_development_dependency(%q<sqlite3-ruby>, [">= 0"])
|
30
33
|
s.add_development_dependency(%q<hoe>, [">= 1.8.0"])
|
31
34
|
else
|
32
35
|
s.add_dependency(%q<unicode>, [">= 0.1"])
|
36
|
+
s.add_dependency(%q<activerecord>, [">= 2.0.0"])
|
33
37
|
s.add_dependency(%q<newgem>, [">= 1.2.3"])
|
38
|
+
s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
|
39
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
34
40
|
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
35
41
|
end
|
36
42
|
else
|
37
43
|
s.add_dependency(%q<unicode>, [">= 0.1"])
|
44
|
+
s.add_dependency(%q<activerecord>, [">= 2.0.0"])
|
38
45
|
s.add_dependency(%q<newgem>, [">= 1.2.3"])
|
46
|
+
s.add_dependency(%q<Shoulda>, [">= 1.2.0"])
|
47
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
39
48
|
s.add_dependency(%q<hoe>, [">= 1.8.0"])
|
40
49
|
end
|
41
50
|
end
|
@@ -21,17 +21,17 @@ module FriendlyId::NonSluggableClassMethods
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def find_some_with_friendly(ids_and_names, options) #:nodoc:#
|
24
|
-
|
24
|
+
|
25
25
|
results = with_scope :find => options do
|
26
|
-
find :all, :conditions => ["#{
|
26
|
+
find :all, :conditions => ["#{quoted_table_name}.#{primary_key} IN (?) OR #{friendly_id_options[:column].to_s} IN (?)",
|
27
27
|
ids_and_names, ids_and_names]
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
expected = expected_size(ids_and_names, options)
|
31
31
|
if results.size != expected
|
32
32
|
raise ActiveRecord::RecordNotFound, "Couldn't find all #{ name.pluralize } with IDs (#{ ids_and_names * ', ' }) AND #{ sanitize_sql options[:conditions] } (found #{ results.size } results, but was looking for #{ expected })"
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
results.each {|r| r.send(:found_using_friendly_id=, true) if ids_and_names.include?(r.friendly_id)}
|
36
36
|
|
37
37
|
results
|
@@ -21,10 +21,18 @@ module FriendlyId::NonSluggableInstanceMethods
|
|
21
21
|
|
22
22
|
# Returns the friendly id, or if none is available, the numeric id.
|
23
23
|
def to_param
|
24
|
-
friendly_id
|
24
|
+
(friendly_id || id).to_s
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
28
|
+
|
29
|
+
def validate_friendly_id
|
30
|
+
if self.class.friendly_id_options[:reserved].include? friendly_id
|
31
|
+
self.errors.add(self.class.friendly_id_options[:column],
|
32
|
+
self.class.friendly_id_options[:reserved_message] % friendly_id)
|
33
|
+
return false
|
34
|
+
end
|
35
|
+
end
|
28
36
|
|
29
37
|
def found_using_friendly_id=(value) #:nodoc#
|
30
38
|
@found_using_friendly_id = value
|
data/lib/friendly_id/slug.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'unicode'
|
1
2
|
# A Slug is a unique, human-friendly identifier for an ActiveRecord.
|
2
3
|
class Slug < ActiveRecord::Base
|
3
4
|
|
@@ -23,12 +24,12 @@ class Slug < ActiveRecord::Base
|
|
23
24
|
# terror in Europe unlike anything ever seen before or after. I'm not
|
24
25
|
# taking any chances.
|
25
26
|
def normalize(slug_text)
|
26
|
-
return "" if slug_text.
|
27
|
-
slug_text.
|
27
|
+
return "" if slug_text.nil? || slug_text == ""
|
28
|
+
Unicode::normalize_KC(slug_text).
|
28
29
|
send(chars_func).
|
29
30
|
# For some reason Spanish ¡ and ¿ are not detected as non-word
|
30
31
|
# characters. Bug in Ruby?
|
31
|
-
|
32
|
+
gsub(/[\W|¡|¿]/u, ' ').
|
32
33
|
strip.
|
33
34
|
gsub(/\s+/u, '-').
|
34
35
|
gsub(/-\z/u, '').
|
@@ -42,12 +43,10 @@ class Slug < ActiveRecord::Base
|
|
42
43
|
return name, sequence
|
43
44
|
end
|
44
45
|
|
45
|
-
# Remove diacritics (accents, umlauts, etc.) from the string.
|
46
|
+
# Remove diacritics (accents, umlauts, etc.) from the string. Borrowed
|
47
|
+
# from "The Ruby Way."
|
46
48
|
def strip_diacritics(string)
|
47
|
-
|
48
|
-
Unicode::normalize_KD(string).unpack('U*').select { |cp|
|
49
|
-
cp < 0x300 || cp > 0x036F
|
50
|
-
}.pack('U*')
|
49
|
+
Unicode::normalize_KD(string).unpack('U*').select { |u| u < 0x300 || u > 0x036F }.pack('U*')
|
51
50
|
end
|
52
51
|
|
53
52
|
# Remove non-ascii characters from the string.
|
@@ -58,9 +57,7 @@ class Slug < ActiveRecord::Base
|
|
58
57
|
private
|
59
58
|
|
60
59
|
def chars_func
|
61
|
-
|
62
|
-
rescue NoMethodError
|
63
|
-
:chars
|
60
|
+
"".respond_to?(:mb_chars) ? :mb_chars : :chars
|
64
61
|
end
|
65
62
|
|
66
63
|
end
|
@@ -78,7 +75,7 @@ class Slug < ActiveRecord::Base
|
|
78
75
|
|
79
76
|
# Raise a FriendlyId::SlugGenerationError if the slug name is blank.
|
80
77
|
def check_for_blank_name #:nodoc:#
|
81
|
-
if name.
|
78
|
+
if name == "" || name.nil?
|
82
79
|
raise FriendlyId::SlugGenerationError.new("The slug text is blank.")
|
83
80
|
end
|
84
81
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module FriendlyId::SluggableClassMethods
|
2
|
-
|
2
|
+
|
3
3
|
include FriendlyId::Helpers
|
4
4
|
|
5
5
|
def self.extended(base) #:nodoc:#
|
@@ -38,6 +38,17 @@ module FriendlyId::SluggableClassMethods
|
|
38
38
|
end
|
39
39
|
|
40
40
|
result
|
41
|
+
rescue ActiveRecord::RecordNotFound => e
|
42
|
+
|
43
|
+
if friendly_id_options[:scope]
|
44
|
+
if !scope
|
45
|
+
e.message << "; expected scope but got none"
|
46
|
+
else
|
47
|
+
e.message << " and scope=#{scope}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
raise e
|
41
52
|
|
42
53
|
end
|
43
54
|
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/friendly_id.rb
CHANGED
@@ -1,20 +1,35 @@
|
|
1
1
|
require 'friendly_id/helpers'
|
2
2
|
require 'friendly_id/slug'
|
3
|
-
require 'friendly_id/shoulda_macros'
|
4
|
-
|
5
3
|
|
6
4
|
# FriendlyId is a comprehensize Rails plugin/gem for slugging and permalinks.
|
7
5
|
module FriendlyId
|
8
6
|
|
7
|
+
# Default options for has_friendly_id.
|
8
|
+
DEFAULT_FRIENDLY_ID_OPTIONS = {
|
9
|
+
:max_length => 255,
|
10
|
+
:method => nil,
|
11
|
+
:reserved => ["new", "index"],
|
12
|
+
:reserved_message => 'can not be "%s"',
|
13
|
+
:scope => nil,
|
14
|
+
:strip_diacritics => false,
|
15
|
+
:strip_non_ascii => false,
|
16
|
+
:use_slug => false }.freeze
|
17
|
+
|
18
|
+
# Valid keys for has_friendly_id options.
|
19
|
+
VALID_FRIENDLY_ID_KEYS = [
|
20
|
+
:max_length,
|
21
|
+
:reserved,
|
22
|
+
:reserved_message,
|
23
|
+
:scope,
|
24
|
+
:strip_diacritics,
|
25
|
+
:strip_non_ascii,
|
26
|
+
:use_slug ].freeze
|
27
|
+
|
9
28
|
# This error is raised when it's not possible to generate a unique slug.
|
10
29
|
class SlugGenerationError < StandardError ; end
|
11
30
|
|
12
31
|
module ClassMethods
|
13
32
|
|
14
|
-
# Default options for friendly_id.
|
15
|
-
DEFAULT_FRIENDLY_ID_OPTIONS = {:method => nil, :use_slug => false, :max_length => 255, :reserved => [], :strip_diacritics => false, :strip_non_ascii => false, :scope => nil}.freeze
|
16
|
-
VALID_FRIENDLY_ID_KEYS = [:use_slug, :max_length, :reserved, :strip_diacritics, :strip_non_ascii, :scope].freeze
|
17
|
-
|
18
33
|
# Set up an ActiveRecord model to use a friendly_id.
|
19
34
|
#
|
20
35
|
# The column argument can be one of your model's columns, or a method
|
@@ -25,12 +40,13 @@ module FriendlyId
|
|
25
40
|
# * <tt>:max_length</tt> - Defaults to 255. The maximum allowed length for a slug.
|
26
41
|
# * <tt>:strip_diacritics</tt> - Defaults to false. If true, it will remove accents, umlauts, etc. from western characters.
|
27
42
|
# * <tt>:strip_non_ascii</tt> - Defaults to false. If true, it will all non-ascii ([^a-z0-9]) characters.
|
28
|
-
# * <tt>:
|
43
|
+
# * <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 be treated the same as if that slug was already taken (numeric extension will be appended). Defaults to ["new", "index"].
|
44
|
+
# * <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'.
|
29
45
|
def has_friendly_id(column, options = {})
|
30
46
|
options.assert_valid_keys VALID_FRIENDLY_ID_KEYS
|
31
47
|
options = DEFAULT_FRIENDLY_ID_OPTIONS.merge(options).merge(:column => column)
|
32
48
|
write_inheritable_attribute :friendly_id_options, options
|
33
|
-
|
49
|
+
class_inheritable_accessor :friendly_id_options
|
34
50
|
|
35
51
|
if options[:use_slug]
|
36
52
|
has_many :slugs, :order => 'id DESC', :as => :sluggable, :dependent => :destroy
|
@@ -44,9 +60,10 @@ module FriendlyId
|
|
44
60
|
require 'friendly_id/non_sluggable_instance_methods'
|
45
61
|
extend NonSluggableClassMethods
|
46
62
|
include NonSluggableInstanceMethods
|
63
|
+
validate_on_create :validate_friendly_id
|
47
64
|
end
|
48
65
|
end
|
49
|
-
|
66
|
+
|
50
67
|
end
|
51
68
|
|
52
69
|
class << self
|
@@ -55,15 +72,6 @@ module FriendlyId
|
|
55
72
|
def enable
|
56
73
|
return if ActiveRecord::Base.methods.include? 'has_friendly_id'
|
57
74
|
ActiveRecord::Base.class_eval { extend FriendlyId::ClassMethods }
|
58
|
-
begin
|
59
|
-
if Rails.version >= "2.3"
|
60
|
-
ActiveSupport::TestCase.class_eval { include FriendlyId::ShouldaMacros }
|
61
|
-
else
|
62
|
-
Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
|
63
|
-
end
|
64
|
-
rescue NoMethodError
|
65
|
-
Test::Unit::TestCase.class_eval { include FriendlyId::ShouldaMacros }
|
66
|
-
end
|
67
75
|
end
|
68
76
|
|
69
77
|
end
|
data/test/models/post.rb
ADDED
data/test/non_slugged_test.rb
CHANGED
@@ -2,84 +2,95 @@ require File.dirname(__FILE__) + '/test_helper'
|
|
2
2
|
|
3
3
|
class NonSluggedTest < Test::Unit::TestCase
|
4
4
|
|
5
|
-
|
5
|
+
context "A non-slugged model with default FriendlyId options" do
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
setup do
|
8
|
+
User.delete_all
|
9
|
+
@user = User.create!(:login => "joe", :email => "joe@example.org")
|
10
|
+
end
|
9
11
|
|
10
|
-
|
11
|
-
|
12
|
-
|
12
|
+
should "have friendly_id options" do
|
13
|
+
assert_not_nil User.friendly_id_options
|
14
|
+
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
16
|
+
should "not have a slug" do
|
17
|
+
assert !@user.respond_to?(:slug)
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
should "be findable by its friendly_id" do
|
21
|
+
assert User.find(@user.friendly_id)
|
22
|
+
end
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
User.find(['bad', 'bad2'])
|
24
|
+
should "be findable by its regular id" do
|
25
|
+
assert User.find(@user.id)
|
25
26
|
end
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
|
28
|
+
should "respect finder conditions" do
|
29
|
+
assert_raises ActiveRecord::RecordNotFound do
|
30
|
+
User.find(@user.friendly_id, :conditions => "1 = 2")
|
31
|
+
end
|
31
32
|
end
|
32
|
-
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
end
|
34
|
+
should "indicate if it was found by its friendly id" do
|
35
|
+
@user = User.find(@user.friendly_id)
|
36
|
+
assert @user.found_using_friendly_id?
|
37
|
+
end
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
should "indicate if it was found by its numeric id" do
|
40
|
+
@user = User.find(@user.id)
|
41
|
+
assert @user.found_using_numeric_id?
|
43
42
|
end
|
44
|
-
|
45
|
-
|
43
|
+
|
44
|
+
should "indicate if it has a better id" do
|
45
|
+
@user = User.find(@user.id)
|
46
|
+
assert @user.has_better_id?
|
46
47
|
end
|
47
|
-
end
|
48
48
|
|
49
|
-
|
50
|
-
|
51
|
-
|
49
|
+
should "not validate if the friendly_id text is reserved" do
|
50
|
+
@user = User.new(:login => "new", :email => "test@example.org")
|
51
|
+
assert !@user.valid?
|
52
|
+
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
should "have always string for a friendly_id" do
|
55
|
+
assert_equal String, @user.to_param.class
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
should "return its id if the friendly_id is null" do
|
59
|
+
@user.login = nil
|
60
|
+
assert_equal @user.id.to_s, @user.to_param
|
61
|
+
end
|
61
62
|
|
62
|
-
def test_user_should_be_considered_found_by_numeric_id_as_default
|
63
|
-
@user = User.new
|
64
|
-
assert @user.found_using_numeric_id?
|
65
|
-
end
|
66
63
|
|
67
|
-
|
68
|
-
@user = User.find(users(:joe).id)
|
69
|
-
assert @user.found_using_numeric_id?
|
70
|
-
assert !@user.found_using_friendly_id?
|
71
|
-
end
|
64
|
+
context "when using an array as the find argument" do
|
72
65
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
66
|
+
setup do
|
67
|
+
@user2 = User.create(:login => "jane", :email => "jane@example.org")
|
68
|
+
end
|
69
|
+
|
70
|
+
should "return results" do
|
71
|
+
assert_equal 2, User.find([@user.friendly_id, @user2.friendly_id]).size
|
72
|
+
end
|
73
|
+
|
74
|
+
should "not allow mixed friendly and non-friendly ids for the same record" do
|
75
|
+
assert_raises ActiveRecord::RecordNotFound do
|
76
|
+
User.find([@user.id, @user.friendly_id]).size
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
should "raise an error when all records are not found" do
|
81
|
+
assert_raises ActiveRecord::RecordNotFound do
|
82
|
+
User.find(['bad', 'bad2'])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
should "indicate if the results were found using a friendly_id" do
|
87
|
+
@users = User.find([@user.id, @user2.friendly_id], :order => "login ASC")
|
88
|
+
assert @users[0].found_using_friendly_id?
|
89
|
+
assert @users[1].found_using_numeric_id?
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
78
93
|
|
79
|
-
def test_should_indicate_there_is_a_better_id_if_found_by_numeric_id
|
80
|
-
@user = User.find(users(:joe).id)
|
81
|
-
assert @user.found_using_numeric_id?
|
82
|
-
assert @user.has_better_id?
|
83
94
|
end
|
84
95
|
|
85
96
|
end
|
data/test/schema.rb
CHANGED
@@ -1,35 +1,40 @@
|
|
1
|
-
ActiveRecord::Schema.define(:version =>
|
1
|
+
ActiveRecord::Schema.define(:version => 1) do
|
2
|
+
|
3
|
+
create_table "books", :force => true do |t|
|
4
|
+
t.column "title", "string"
|
5
|
+
t.column "type", "text"
|
6
|
+
end
|
2
7
|
|
3
8
|
create_table "posts", :force => true do |t|
|
4
|
-
t.string
|
5
|
-
t.
|
6
|
-
t.
|
7
|
-
t.
|
9
|
+
t.column "title", "string"
|
10
|
+
t.column "content", "text"
|
11
|
+
t.column "created_at", "datetime"
|
12
|
+
t.column "updated_at", "datetime"
|
8
13
|
end
|
9
14
|
|
10
15
|
create_table "users", :force => true do |t|
|
11
|
-
t.
|
12
|
-
t.
|
13
|
-
t.
|
14
|
-
t.
|
16
|
+
t.column "login", "string"
|
17
|
+
t.column "email", "string"
|
18
|
+
t.column "created_at", "datetime"
|
19
|
+
t.column "updated_at", "datetime"
|
15
20
|
end
|
16
21
|
|
17
22
|
create_table "people", :force => true do |t|
|
18
|
-
t.
|
19
|
-
t.
|
23
|
+
t.column "name", "string"
|
24
|
+
t.column "country_id", "integer"
|
20
25
|
end
|
21
26
|
|
22
27
|
create_table "countries", :force => true do |t|
|
23
|
-
t.
|
28
|
+
t.column "name", "string"
|
24
29
|
end
|
25
30
|
|
26
31
|
create_table "slugs", :force => true do |t|
|
27
|
-
t.
|
28
|
-
t.
|
29
|
-
t.
|
30
|
-
t.
|
31
|
-
t.
|
32
|
-
t.
|
32
|
+
t.column "name", "string"
|
33
|
+
t.column "sluggable_id", "integer"
|
34
|
+
t.column "sequence", "integer", :null => false, :default => 1
|
35
|
+
t.column "sluggable_type", "string", :limit => 40
|
36
|
+
t.column "scope", "string", :limit => 40
|
37
|
+
t.column "created_at", "datetime"
|
33
38
|
end
|
34
39
|
|
35
40
|
add_index "slugs", ["sluggable_id"], :name => "index_slugs_on_sluggable_id"
|