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 +8 -0
- data/MIT-LICENSE +1 -1
- data/README.rdoc +11 -2
- data/Rakefile +16 -1
- data/generators/friendly_id/friendly_id_generator.rb +20 -4
- data/init.rb +1 -3
- data/lib/friendly_id.rb +58 -98
- data/lib/friendly_id/helpers.rb +2 -5
- data/lib/friendly_id/non_sluggable_class_methods.rb +3 -5
- data/lib/friendly_id/non_sluggable_instance_methods.rb +7 -5
- data/lib/friendly_id/slug.rb +1 -3
- data/lib/friendly_id/sluggable_class_methods.rb +4 -3
- data/lib/friendly_id/sluggable_instance_methods.rb +16 -3
- data/lib/friendly_id/tasks.rb +1 -2
- data/lib/friendly_id/version.rb +1 -3
- data/lib/tasks/friendly_id.rake +0 -2
- data/test/cached_slug_test.rb +3 -3
- data/test/custom_slug_normalizer_test.rb +5 -5
- data/test/models/district.rb +1 -1
- data/test/models/legacy_thing.rb +4 -0
- data/test/non_slugged_test.rb +11 -11
- data/test/schema.rb +4 -0
- data/test/slug_test.rb +5 -5
- data/test/slugged_model_test.rb +50 -17
- data/test/sti_test.rb +1 -1
- data/test/test_helper.rb +1 -0
- metadata +18 -8
- data/Manifest.txt +0 -43
- data/config/website.yml +0 -2
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
|
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@
|
349
|
-
{Adrian Mugnolo}[mailto:adrian@
|
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
|
-
|
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
|
-
|
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
data/lib/friendly_id.rb
CHANGED
@@ -1,115 +1,75 @@
|
|
1
|
-
|
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
|
-
|
4
|
-
|
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
|
-
|
11
|
-
:max_length
|
12
|
-
:
|
13
|
-
:
|
14
|
-
|
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
|
-
#
|
22
|
-
|
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
|
-
:
|
30
|
-
:use_slug
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
-
|
114
|
-
FriendlyId
|
73
|
+
class ActiveRecord::Base
|
74
|
+
extend FriendlyId
|
115
75
|
end
|
data/lib/friendly_id/helpers.rb
CHANGED
@@ -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[:
|
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[:
|
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[:
|
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[:
|
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
|
data/lib/friendly_id/slug.rb
CHANGED
@@ -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
|
-
|
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[:
|
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
|
data/lib/friendly_id/tasks.rb
CHANGED
@@ -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, :
|
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|
|
data/lib/friendly_id/version.rb
CHANGED
data/lib/tasks/friendly_id.rake
CHANGED
data/test/cached_slug_test.rb
CHANGED
@@ -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
|
-
|
40
|
-
assert_equal 2,
|
41
|
-
assert_equal "paris--2",
|
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::
|
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
|
-
|
20
|
-
assert_equal "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3",
|
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
|
-
|
26
|
-
assert_equal "a94a8fe5cc",
|
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
|
data/test/models/district.rb
CHANGED
data/test/non_slugged_test.rb
CHANGED
@@ -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
|
-
|
41
|
-
assert
|
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
|
-
|
46
|
-
assert
|
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
|
-
|
51
|
-
assert
|
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
|
-
|
56
|
-
assert
|
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
|
-
|
93
|
-
assert
|
94
|
-
assert
|
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
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
assert
|
19
|
-
assert
|
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
|
data/test/slugged_model_test.rb
CHANGED
@@ -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::
|
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
|
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
|
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
|
-
|
109
|
-
assert_match(/#{'ñ'}/,
|
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
|
-
|
114
|
-
assert_equal "katakana-ゲコゴサザシジ",
|
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
|
-
|
119
|
-
assert_equal
|
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
|
-
|
124
|
-
assert_equal
|
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
|
-
|
129
|
-
assert_equal
|
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
|
-
|
161
|
-
assert_no_match(/#{'ñ'}/,
|
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
|
-
|
172
|
-
assert_equal "katakana",
|
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::
|
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
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.
|
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-
|
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.
|
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