friendly_id 3.0.6 → 3.1.0.pre
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/Changelog.md +10 -0
- data/Contributors.md +1 -0
- data/Guide.md +24 -35
- data/README.md +3 -3
- data/Rakefile +0 -5
- data/extras/bench.rb +5 -1
- data/extras/prof.rb +9 -4
- data/lib/friendly_id.rb +35 -7
- data/lib/friendly_id/active_record.rb +32 -17
- data/lib/friendly_id/active_record_adapter/configuration.rb +1 -0
- data/lib/friendly_id/active_record_adapter/finders.rb +136 -130
- data/lib/friendly_id/active_record_adapter/relation.rb +129 -0
- data/lib/friendly_id/active_record_adapter/simple_model.rb +2 -62
- data/lib/friendly_id/active_record_adapter/slug.rb +3 -2
- data/lib/friendly_id/active_record_adapter/slugged_model.rb +13 -145
- data/lib/friendly_id/configuration.rb +1 -1
- data/lib/friendly_id/railtie.rb +2 -2
- data/lib/friendly_id/slug_string.rb +22 -392
- data/lib/friendly_id/slugged.rb +7 -3
- data/lib/friendly_id/test.rb +1 -2
- data/lib/friendly_id/version.rb +3 -3
- data/test/active_record_adapter/ar_test_helper.rb +14 -6
- data/test/active_record_adapter/cached_slug_test.rb +10 -0
- data/test/active_record_adapter/core.rb +15 -0
- data/test/active_record_adapter/slugged.rb +0 -1
- data/test/active_record_adapter/support/models.rb +4 -0
- data/test/active_record_adapter/tasks_test.rb +1 -1
- data/test/friendly_id_test.rb +12 -16
- data/test/test_helper.rb +9 -10
- metadata +18 -16
- data/lib/friendly_id/finders.rb +0 -109
- data/test/slug_string_test.rb +0 -88
data/lib/friendly_id/version.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
require File.expand_path('../../test_helper', __FILE__)
|
2
|
-
|
3
2
|
require "logger"
|
4
3
|
require "active_record"
|
5
|
-
|
4
|
+
begin
|
5
|
+
require "active_support/log_subscriber"
|
6
|
+
rescue MissingSourceFile
|
7
|
+
end
|
6
8
|
|
7
|
-
# ActiveRecord
|
9
|
+
# If you want to see the ActiveRecord log, invoke the tests using `rake test LOG=true`
|
10
|
+
ActiveRecord::Base.logger = Logger.new($stdout) if ENV["LOG"]
|
8
11
|
|
9
|
-
require
|
12
|
+
require "friendly_id/active_record"
|
10
13
|
require File.expand_path("../../../generators/friendly_id/templates/create_slugs", __FILE__)
|
11
14
|
require File.expand_path("../support/models", __FILE__)
|
12
15
|
require File.expand_path('../core', __FILE__)
|
@@ -58,6 +61,10 @@ class Person < ActiveRecord::Base
|
|
58
61
|
|
59
62
|
end
|
60
63
|
|
64
|
+
# A model that doesn't use FriendlyId
|
65
|
+
class Unfriendly < ActiveRecord::Base
|
66
|
+
end
|
67
|
+
|
61
68
|
# A slugged model that uses a scope
|
62
69
|
class Resident < ActiveRecord::Base
|
63
70
|
belongs_to :country
|
@@ -71,7 +78,7 @@ class Country < ActiveRecord::Base
|
|
71
78
|
has_friendly_id :name, :use_slug => true
|
72
79
|
end
|
73
80
|
|
74
|
-
# A model that doesn
|
81
|
+
# A model that doesn't use slugs
|
75
82
|
class User < ActiveRecord::Base
|
76
83
|
has_friendly_id :name
|
77
84
|
has_many :houses
|
@@ -92,7 +99,8 @@ end
|
|
92
99
|
# A model that uses default slug settings and has a named scope
|
93
100
|
class Post < ActiveRecord::Base
|
94
101
|
has_friendly_id :name, :use_slug => true
|
95
|
-
|
102
|
+
def self.named_scope(*args) scope(*args) end if FriendlyId.on_ar3?
|
103
|
+
named_scope :published, :conditions => { :published => true }
|
96
104
|
end
|
97
105
|
|
98
106
|
# Model that uses a custom table name
|
@@ -54,6 +54,16 @@ module FriendlyId
|
|
54
54
|
assert_match(/2\z/, instance_2.send(cache_column))
|
55
55
|
end
|
56
56
|
|
57
|
+
test "#friendly_id should check the cached value by default" do
|
58
|
+
instance.expects(:slug).never
|
59
|
+
instance.friendly_id
|
60
|
+
end
|
61
|
+
|
62
|
+
test "#friendly_id should skip the cache if invoked with true" do
|
63
|
+
instance.expects(:slug)
|
64
|
+
instance.friendly_id(true)
|
65
|
+
end
|
66
|
+
|
57
67
|
end
|
58
68
|
end
|
59
69
|
end
|
@@ -30,6 +30,10 @@ module FriendlyId
|
|
30
30
|
:save!
|
31
31
|
end
|
32
32
|
|
33
|
+
def unfriendly_class
|
34
|
+
Unfriendly
|
35
|
+
end
|
36
|
+
|
33
37
|
def validation_exceptions
|
34
38
|
[ActiveRecord::RecordInvalid, FriendlyId::ReservedError, FriendlyId::BlankError]
|
35
39
|
end
|
@@ -72,6 +76,12 @@ module FriendlyId
|
|
72
76
|
assert_equal 2, klass.find([instance.friendly_id, second]).size
|
73
77
|
end
|
74
78
|
|
79
|
+
test "should not raise error when finding with empty array" do
|
80
|
+
assert_nothing_raised do
|
81
|
+
klass.find []
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
75
85
|
test "models should raise an error when not all records are found" do
|
76
86
|
assert_raises(ActiveRecord::RecordNotFound) do
|
77
87
|
klass.find([instance.friendly_id, 'bad-friendly-id'])
|
@@ -92,6 +102,11 @@ module FriendlyId
|
|
92
102
|
end
|
93
103
|
end
|
94
104
|
|
105
|
+
test "should not change failure behavior for models not using friendly_id" do
|
106
|
+
assert_raise ActiveRecord::RecordNotFound do
|
107
|
+
unfriendly_class.find(-1)
|
108
|
+
end
|
109
|
+
end
|
95
110
|
end
|
96
111
|
end
|
97
112
|
end
|
data/test/friendly_id_test.rb
CHANGED
@@ -1,55 +1,51 @@
|
|
1
1
|
require File.expand_path('../test_helper', __FILE__)
|
2
2
|
|
3
3
|
module FriendlyId
|
4
|
-
|
5
4
|
module Test
|
6
|
-
|
7
5
|
class FriendlyIdTest < ::Test::Unit::TestCase
|
8
|
-
|
9
6
|
test "should parse a friendly_id name and sequence" do
|
10
|
-
assert_equal ["test",
|
7
|
+
assert_equal ["test", 2], "test--2".parse_friendly_id
|
11
8
|
end
|
12
9
|
|
13
10
|
test "should parse a friendly_id name and a double digit sequence" do
|
14
|
-
assert_equal ["test",
|
11
|
+
assert_equal ["test", 12], "test--12".parse_friendly_id
|
15
12
|
end
|
16
13
|
|
17
14
|
test "should parse with a default sequence of 1" do
|
18
|
-
assert_equal ["test",
|
15
|
+
assert_equal ["test", 1], "test".parse_friendly_id
|
19
16
|
end
|
20
17
|
|
21
18
|
test "should be parseable with a custom separator" do
|
22
|
-
assert_equal ["test",
|
19
|
+
assert_equal ["test", 2], "test:2".parse_friendly_id(":")
|
23
20
|
end
|
24
21
|
|
25
22
|
test "should be parseable with a custom separator and a double digit sequence" do
|
26
|
-
assert_equal ["test",
|
23
|
+
assert_equal ["test", 12], "test:12".parse_friendly_id(":")
|
27
24
|
end
|
28
25
|
|
29
26
|
test "should parse when default sequence separator occurs in friendly_id name" do
|
30
|
-
assert_equal ["test--test",
|
27
|
+
assert_equal ["test--test", 2], "test--test--2".parse_friendly_id
|
31
28
|
end
|
32
29
|
|
33
30
|
test "should parse when custom sequence separator occurs in friendly_id name" do
|
34
|
-
assert_equal ["test:test",
|
31
|
+
assert_equal ["test:test", 2], "test:test:2".parse_friendly_id(":")
|
35
32
|
end
|
36
33
|
|
37
34
|
test "should parse when sequence separator and number occur in friendly_id name" do
|
38
|
-
assert_equal ["test--2--test",
|
35
|
+
assert_equal ["test--2--test", 1], "test--2--test".parse_friendly_id
|
39
36
|
end
|
40
37
|
|
41
38
|
test "should parse when sequence separator, number and sequence occur in friendly_id name" do
|
42
|
-
assert_equal ["test--2--test",
|
39
|
+
assert_equal ["test--2--test", 2], "test--2--test--2".parse_friendly_id
|
43
40
|
end
|
44
41
|
|
45
42
|
test "should parse when double digit sequence separator, number and sequence occur in friendly_id name" do
|
46
|
-
assert_equal ["test--2--test",
|
43
|
+
assert_equal ["test--2--test", 12], "test--2--test--12".parse_friendly_id
|
47
44
|
end
|
48
45
|
|
49
46
|
test "should parse with a separator and no sequence" do
|
50
|
-
assert_equal ["test",
|
47
|
+
assert_equal ["test", 1], "test--".parse_friendly_id
|
51
48
|
end
|
52
|
-
|
53
49
|
end
|
54
50
|
end
|
55
|
-
end
|
51
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
+
$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
2
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
3
|
+
$:.uniq!
|
4
|
+
|
1
5
|
$KCODE = "UTF8" if RUBY_VERSION < "1.9"
|
2
6
|
$VERBOSE = false
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Fall back on doing an unlocked resolve at runtime.
|
7
|
-
require "rubygems"
|
8
|
-
require "bundler"
|
9
|
-
Bundler.setup
|
10
|
-
end
|
7
|
+
require "rubygems"
|
8
|
+
require "bundler"
|
9
|
+
Bundler.setup
|
11
10
|
require "test/unit"
|
12
11
|
require "mocha"
|
13
12
|
require "active_support"
|
14
13
|
# require "ruby-debug"
|
15
|
-
require
|
16
|
-
require
|
14
|
+
require "friendly_id"
|
15
|
+
require "friendly_id/test"
|
metadata
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: friendly_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: true
|
5
5
|
segments:
|
6
6
|
- 3
|
7
|
+
- 1
|
7
8
|
- 0
|
8
|
-
-
|
9
|
-
version: 3.0.
|
9
|
+
- pre
|
10
|
+
version: 3.1.0.pre
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Norman Clarke
|
@@ -16,7 +17,7 @@ autorequire:
|
|
16
17
|
bindir: bin
|
17
18
|
cert_chain: []
|
18
19
|
|
19
|
-
date: 2010-
|
20
|
+
date: 2010-07-15 00:00:00 -03:00
|
20
21
|
default_executable:
|
21
22
|
dependencies:
|
22
23
|
- !ruby/object:Gem::Dependency
|
@@ -29,12 +30,12 @@ dependencies:
|
|
29
30
|
- !ruby/object:Gem::Version
|
30
31
|
segments:
|
31
32
|
- 2
|
32
|
-
-
|
33
|
-
version: "2.
|
33
|
+
- 3
|
34
|
+
version: "2.3"
|
34
35
|
type: :runtime
|
35
36
|
version_requirements: *id001
|
36
37
|
- !ruby/object:Gem::Dependency
|
37
|
-
name:
|
38
|
+
name: babosa
|
38
39
|
prerelease: false
|
39
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
41
|
none: false
|
@@ -42,9 +43,10 @@ dependencies:
|
|
42
43
|
- - ">="
|
43
44
|
- !ruby/object:Gem::Version
|
44
45
|
segments:
|
45
|
-
-
|
46
|
-
-
|
47
|
-
|
46
|
+
- 0
|
47
|
+
- 1
|
48
|
+
- 0
|
49
|
+
version: 0.1.0
|
48
50
|
type: :runtime
|
49
51
|
version_requirements: *id002
|
50
52
|
description: " FriendlyId is the \"Swiss Army bulldozer\" of slugging and permalink plugins\n for Ruby on Rails. It allows you to create pretty URL\xE2\x80\x99s and work with\n human-friendly strings as if they were numeric ids for ActiveRecord models.\n"
|
@@ -62,12 +64,12 @@ files:
|
|
62
64
|
- lib/friendly_id/active_record.rb
|
63
65
|
- lib/friendly_id/active_record_adapter/configuration.rb
|
64
66
|
- lib/friendly_id/active_record_adapter/finders.rb
|
67
|
+
- lib/friendly_id/active_record_adapter/relation.rb
|
65
68
|
- lib/friendly_id/active_record_adapter/simple_model.rb
|
66
69
|
- lib/friendly_id/active_record_adapter/slug.rb
|
67
70
|
- lib/friendly_id/active_record_adapter/slugged_model.rb
|
68
71
|
- lib/friendly_id/active_record_adapter/tasks.rb
|
69
72
|
- lib/friendly_id/configuration.rb
|
70
|
-
- lib/friendly_id/finders.rb
|
71
73
|
- lib/friendly_id/railtie.rb
|
72
74
|
- lib/friendly_id/sequel.rb
|
73
75
|
- lib/friendly_id/slug_string.rb
|
@@ -107,7 +109,6 @@ files:
|
|
107
109
|
- test/active_record_adapter/support/models.rb
|
108
110
|
- test/active_record_adapter/tasks_test.rb
|
109
111
|
- test/friendly_id_test.rb
|
110
|
-
- test/slug_string_test.rb
|
111
112
|
- test/test_helper.rb
|
112
113
|
- extras/bench.rb
|
113
114
|
- extras/extras.rb
|
@@ -135,11 +136,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
135
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
137
|
none: false
|
137
138
|
requirements:
|
138
|
-
- - "
|
139
|
+
- - ">"
|
139
140
|
- !ruby/object:Gem::Version
|
140
141
|
segments:
|
141
|
-
-
|
142
|
-
|
142
|
+
- 1
|
143
|
+
- 3
|
144
|
+
- 1
|
145
|
+
version: 1.3.1
|
143
146
|
requirements: []
|
144
147
|
|
145
148
|
rubyforge_project: friendly-id
|
@@ -160,4 +163,3 @@ test_files:
|
|
160
163
|
- test/active_record_adapter/sti_test.rb
|
161
164
|
- test/active_record_adapter/tasks_test.rb
|
162
165
|
- test/friendly_id_test.rb
|
163
|
-
- test/slug_string_test.rb
|
data/lib/friendly_id/finders.rb
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
module FriendlyId
|
2
|
-
|
3
|
-
module Finders
|
4
|
-
|
5
|
-
module Base
|
6
|
-
|
7
|
-
extend Forwardable
|
8
|
-
|
9
|
-
def_delegators :model_class, :base_class, :friendly_id_config,
|
10
|
-
:primary_key, :quoted_table_name, :sanitize_sql, :table_name
|
11
|
-
|
12
|
-
# Is the id friendly or numeric? Not that the return value here is
|
13
|
-
# +false+ if the +id+ is definitely not friendly, and +nil+ if it can
|
14
|
-
# not be determined.
|
15
|
-
# The return value will be:
|
16
|
-
# * +true+ - if the id is definitely friendly (i.e., any string with non-numeric characters)
|
17
|
-
# * +false+ - if the id is definitely unfriendly (i.e., an Integer, a model instance, etc.)
|
18
|
-
# * +nil+ - if it can not be determined (i.e., a numeric string like "206".)
|
19
|
-
# @return [true, false, nil]
|
20
|
-
# @see #unfriendly?
|
21
|
-
def self.friendly?(id)
|
22
|
-
if id.is_a?(Integer) or id.is_a?(Symbol) or id.class.respond_to? :friendly_id_config
|
23
|
-
return false
|
24
|
-
elsif id.to_i.to_s != id.to_s
|
25
|
-
return true
|
26
|
-
else
|
27
|
-
return nil
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# Is the id numeric?
|
32
|
-
# @return [true, false, nil] +true+ if definitely unfriendly, +false+ if
|
33
|
-
# definitely friendly, else +nil+.
|
34
|
-
# @see #friendly?
|
35
|
-
def self.unfriendly?(id)
|
36
|
-
!friendly?(id) unless friendly?(id) == nil
|
37
|
-
end
|
38
|
-
|
39
|
-
def initialize(ids, model_class, options={})
|
40
|
-
self.ids = ids
|
41
|
-
self.options = options
|
42
|
-
self.model_class = model_class
|
43
|
-
self.scope = options.delete :scope
|
44
|
-
end
|
45
|
-
|
46
|
-
# An array of ids; can be both friendly and unfriendly.
|
47
|
-
attr_accessor :ids
|
48
|
-
|
49
|
-
# The ActiveRecord query options
|
50
|
-
attr_accessor :options
|
51
|
-
|
52
|
-
# The FriendlyId scope
|
53
|
-
attr_accessor :scope
|
54
|
-
|
55
|
-
# The model class being used to perform the query.
|
56
|
-
attr_accessor :model_class
|
57
|
-
|
58
|
-
# Perform the find.
|
59
|
-
def find
|
60
|
-
raise NotImplementedError
|
61
|
-
end
|
62
|
-
|
63
|
-
private
|
64
|
-
|
65
|
-
def ids=(ids)
|
66
|
-
@ids = [ids].flatten
|
67
|
-
end
|
68
|
-
alias :id= :ids=
|
69
|
-
|
70
|
-
def scope=(scope)
|
71
|
-
unless scope.nil?
|
72
|
-
@scope = scope.respond_to?(:to_param) ? scope.to_param : scope.to_s
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
module Single
|
78
|
-
# Is the id definitely friendly?
|
79
|
-
# @see Finder::friendly?
|
80
|
-
def friendly?
|
81
|
-
Base.friendly?(id)
|
82
|
-
end
|
83
|
-
|
84
|
-
# Is the id definitely unfriendly?
|
85
|
-
# @see Finder::unfriendly?
|
86
|
-
def unfriendly?
|
87
|
-
Base.unfriendly?(id)
|
88
|
-
end
|
89
|
-
|
90
|
-
private
|
91
|
-
|
92
|
-
# The id (numeric or friendly).
|
93
|
-
def id
|
94
|
-
ids[0]
|
95
|
-
end
|
96
|
-
|
97
|
-
# The slug name; i.e. if "my-title--2", then "my-title".
|
98
|
-
def name
|
99
|
-
id.to_s.parse_friendly_id(friendly_id_config.sequence_separator)[0]
|
100
|
-
end
|
101
|
-
|
102
|
-
# The slug sequence; i.e. if "my-title--2", then "2".
|
103
|
-
def sequence
|
104
|
-
id.to_s.parse_friendly_id(friendly_id_config.sequence_separator)[1]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
end
|