friendly_id4 4.0.0.pre → 4.0.0.pre3
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/.gitignore +9 -0
- data/ABOUT.md +139 -0
- data/Guide.md +405 -0
- data/README.md +65 -47
- data/Rakefile +12 -16
- data/bench.rb +71 -0
- data/friendly_id.gemspec +29 -0
- data/lib/friendly_id.rb +9 -116
- data/lib/friendly_id/base.rb +29 -0
- data/lib/friendly_id/configuration.rb +31 -0
- data/lib/friendly_id/finder_methods.rb +14 -0
- data/lib/friendly_id/history.rb +29 -0
- data/lib/friendly_id/migration.rb +17 -0
- data/lib/friendly_id/model.rb +22 -0
- data/lib/friendly_id/object_utils.rb +27 -0
- data/lib/friendly_id/scoped.rb +24 -2
- data/lib/friendly_id/slug_sequencer.rb +79 -0
- data/lib/friendly_id/slugged.rb +11 -84
- data/lib/friendly_id/version.rb +1 -1
- data/lib/generators/friendly_id_generator.rb +21 -0
- data/test/core_test.rb +23 -56
- data/test/helper.rb +41 -0
- data/test/history_test.rb +46 -0
- data/test/object_utils_test.rb +18 -0
- data/test/scoped_test.rb +30 -49
- data/test/shared.rb +47 -0
- data/test/slugged_test.rb +31 -52
- metadata +56 -22
- data/lib/friendly_id/test.rb +0 -23
- data/lib/friendly_id/test/generic.rb +0 -84
- data/test/test_helper.rb +0 -23
data/test/helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require "active_record"
|
4
|
+
require "active_support"
|
5
|
+
require "friendly_id"
|
6
|
+
$VERBOSE = true
|
7
|
+
|
8
|
+
ActiveRecord::Migration.verbose = false
|
9
|
+
|
10
|
+
# Change the connection args as you see fit to test against different adapters.
|
11
|
+
ActiveRecord::Base.establish_connection \
|
12
|
+
:adapter => "sqlite3",
|
13
|
+
:database => ":memory:"
|
14
|
+
|
15
|
+
# If you want to see the ActiveRecord log, invoke the tests using `rake test LOG=true`
|
16
|
+
if ENV["LOG"]
|
17
|
+
require "logger"
|
18
|
+
ActiveRecord::Base.logger = Logger.new($stdout)
|
19
|
+
end
|
20
|
+
|
21
|
+
User, Book = ["users", "books"].map do |table_name|
|
22
|
+
ActiveRecord::Migration.create_table table_name do |t|
|
23
|
+
t.string :name
|
24
|
+
t.boolean :active
|
25
|
+
end
|
26
|
+
Class.new(ActiveRecord::Base)
|
27
|
+
end
|
28
|
+
|
29
|
+
def transaction
|
30
|
+
ActiveRecord::Base.transaction { yield ; raise ActiveRecord::Rollback }
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_instance_of(*args)
|
34
|
+
klass = args.shift
|
35
|
+
args[0] ||= {:name => "a"}
|
36
|
+
transaction { yield klass.create!(*args) }
|
37
|
+
end
|
38
|
+
|
39
|
+
def migration
|
40
|
+
yield ActiveRecord::Migration
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path("../helper.rb", __FILE__)
|
2
|
+
require "friendly_id/migration"
|
3
|
+
|
4
|
+
CreateFriendlyIdSlugs.up
|
5
|
+
|
6
|
+
migration do |m|
|
7
|
+
m.add_column :users, :slug, :string
|
8
|
+
end
|
9
|
+
|
10
|
+
User.send :include, FriendlyId::History
|
11
|
+
User.has_friendly_id :name
|
12
|
+
|
13
|
+
setup {User}
|
14
|
+
|
15
|
+
|
16
|
+
test "should insert record in slugs table on create" do |klass|
|
17
|
+
with_instance_of(klass) {|record| assert !record.friendly_id_slugs.empty?}
|
18
|
+
end
|
19
|
+
|
20
|
+
test "should not create new slug record if friendly_id is not changed" do |klass|
|
21
|
+
with_instance_of(klass) do |record|
|
22
|
+
record.active = true
|
23
|
+
record.save!
|
24
|
+
assert_equal 1, FriendlyIdSlug.count
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
test "should create new slug record when friendly_id changes" do |klass|
|
29
|
+
with_instance_of(klass) do |record|
|
30
|
+
record.name = record.name + "b"
|
31
|
+
record.save!
|
32
|
+
assert_equal 2, FriendlyIdSlug.count
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
test "should be findable by old slugs" do |klass|
|
37
|
+
with_instance_of(klass) do |record|
|
38
|
+
old_friendly_id = record.friendly_id
|
39
|
+
record.name = record.name + "b"
|
40
|
+
record.save!
|
41
|
+
assert found = klass.find_by_friendly_id(old_friendly_id)
|
42
|
+
assert !found.readonly?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
require File.expand_path("../shared.rb", __FILE__)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path("../helper.rb", __FILE__)
|
2
|
+
|
3
|
+
test "strings with letters are friendly_ids" do
|
4
|
+
assert "a".friendly_id?
|
5
|
+
end
|
6
|
+
|
7
|
+
test "integers should be unfriendly ids" do
|
8
|
+
assert 1.unfriendly_id?
|
9
|
+
end
|
10
|
+
|
11
|
+
test "numeric strings are neither friendly nor unfriendly" do
|
12
|
+
assert_equal nil, "1".friendly_id?
|
13
|
+
assert_equal nil, "1".unfriendly_id?
|
14
|
+
end
|
15
|
+
|
16
|
+
test "ActiveRecord::Base instances should be unfriendly_ids" do
|
17
|
+
assert User.new.unfriendly_id?
|
18
|
+
end
|
data/test/scoped_test.rb
CHANGED
@@ -1,61 +1,42 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
require File.expand_path("../
|
3
|
-
require "friendly_id/scoped"
|
2
|
+
require File.expand_path("../helper", __FILE__)
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
t.integer :city_id
|
4
|
+
migration do |m|
|
5
|
+
m.add_column :books, :slug, :string
|
6
|
+
m.add_column :books, :user_id, :integer
|
9
7
|
end
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
Restaurant.belongs_to :city
|
17
|
-
City.has_many :restaurants
|
18
|
-
City.send :include, FriendlyId::Slugged
|
19
|
-
Restaurant.send :include, FriendlyId::Scoped
|
20
|
-
Restaurant.has_friendly_id :name, :scope => :city
|
21
|
-
|
22
|
-
class ScopedTest < Test::Unit::TestCase
|
9
|
+
User.has_many :books
|
10
|
+
Book.belongs_to :user
|
11
|
+
Book.send :include, FriendlyId::Scoped
|
12
|
+
Book.has_friendly_id :name, :scope => :user
|
23
13
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
test "should detect scope column from belongs_to relation" do
|
30
|
-
assert_equal "city_id", Restaurant.friendly_id_config.scope_column
|
31
|
-
end
|
14
|
+
test "should detect scope column from belongs_to relation" do
|
15
|
+
assert_equal "user_id", Book.friendly_id_config.scope_column
|
16
|
+
end
|
32
17
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
18
|
+
test "should detect scope column from explicit column name" do
|
19
|
+
klass = Class.new(ActiveRecord::Base)
|
20
|
+
klass.has_friendly_id :empty, :scope => :dummy
|
21
|
+
assert_equal "dummy", klass.friendly_id_config.scope_column
|
22
|
+
end
|
38
23
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
assert_equal r1.friendly_id, r2.friendly_id
|
24
|
+
test "should allow duplicate slugs outside scope" do
|
25
|
+
transaction do
|
26
|
+
book1 = Book.create! :name => "a", :user => User.create!(:name => "a")
|
27
|
+
book2 = Book.create! :name => "a", :user => User.create!(:name => "b")
|
28
|
+
assert_equal book1.friendly_id, book2.friendly_id
|
45
29
|
end
|
30
|
+
end
|
46
31
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
32
|
+
test "should not allow duplicate slugs inside scope" do
|
33
|
+
with_instance_of User do |user|
|
34
|
+
book1 = Book.create! :name => "a", :user => user
|
35
|
+
book2 = Book.create! :name => "a", :user => user
|
36
|
+
assert book1.friendly_id != book2.friendly_id
|
52
37
|
end
|
38
|
+
end
|
53
39
|
|
54
|
-
|
55
|
-
city = City.create! :name => "Nuñez"
|
56
|
-
old = city.friendly_id
|
57
|
-
city.save!
|
58
|
-
assert_equal old, city.friendly_id
|
59
|
-
end
|
40
|
+
setup { Book }
|
60
41
|
|
61
|
-
|
42
|
+
require File.expand_path("../shared.rb", __FILE__)
|
data/test/shared.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
test "finds should respect conditions" do |klass|
|
2
|
+
with_instance_of(klass) do |record|
|
3
|
+
assert_raise(ActiveRecord::RecordNotFound) do
|
4
|
+
klass.where("1 = 2").find record.friendly_id
|
5
|
+
end
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
test "should be findable by friendly id" do |klass|
|
10
|
+
with_instance_of(klass) {|record| assert klass.find record.friendly_id}
|
11
|
+
end
|
12
|
+
|
13
|
+
test "should be findable by id as integer" do |klass|
|
14
|
+
with_instance_of(klass) {|record| assert klass.find record.id.to_i}
|
15
|
+
end
|
16
|
+
|
17
|
+
test "should be findable by id as string" do |klass|
|
18
|
+
with_instance_of(klass) {|record| assert klass.find record.id.to_s}
|
19
|
+
end
|
20
|
+
|
21
|
+
test "should be findable by numeric friendly_id" do |klass|
|
22
|
+
with_instance_of(klass, :name => "206") {|record| assert klass.find record.friendly_id}
|
23
|
+
end
|
24
|
+
|
25
|
+
test "to_param should return the friendly_id" do |klass|
|
26
|
+
with_instance_of(klass) {|record| assert_equal record.friendly_id, record.to_param}
|
27
|
+
end
|
28
|
+
|
29
|
+
test "should be findable by themselves" do |klass|
|
30
|
+
with_instance_of(klass) {|record| assert_equal record, klass.find(record)}
|
31
|
+
end
|
32
|
+
|
33
|
+
test "updating record's other values should not change the friendly_id" do |klass|
|
34
|
+
with_instance_of klass do |record|
|
35
|
+
old = record.friendly_id
|
36
|
+
record.update_attributes! :active => false
|
37
|
+
assert klass.find old
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
test "instances found by a single id should not be read-only" do |klass|
|
42
|
+
with_instance_of(klass) {|record| assert !klass.find(record.friendly_id).readonly?}
|
43
|
+
end
|
44
|
+
|
45
|
+
test "failing finds with unfriendly_id should raise errors normally" do |klass|
|
46
|
+
assert_raise(ActiveRecord::RecordNotFound) {klass.find 0}
|
47
|
+
end
|
data/test/slugged_test.rb
CHANGED
@@ -1,64 +1,43 @@
|
|
1
|
-
require File.expand_path("../
|
2
|
-
require "friendly_id/slugged"
|
1
|
+
require File.expand_path("../helper.rb", __FILE__)
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def instance(name = "user")
|
9
|
-
@instance ||= klass.create!(:name => name)
|
10
|
-
end
|
11
|
-
|
12
|
-
def klass
|
13
|
-
return @@klass if defined?(@@klass)
|
14
|
-
@@klass = make_model("slugged_model", :name) do |t|
|
15
|
-
t.string :name, :unique => true
|
16
|
-
t.string :slug, :unique => true
|
17
|
-
t.boolean :active, :default => true
|
18
|
-
end
|
19
|
-
@@klass.send :include, FriendlyId::Slugged
|
20
|
-
@@klass
|
3
|
+
[User, Book].map do |klass|
|
4
|
+
migration do |m|
|
5
|
+
m.add_column klass.table_name, :slug, :string
|
6
|
+
m.add_index klass.table_name, :slug, :unique => true
|
21
7
|
end
|
8
|
+
klass.send :include, FriendlyId::Slugged
|
9
|
+
klass.has_friendly_id :name
|
10
|
+
end
|
22
11
|
|
23
|
-
|
24
|
-
return @@other_class if defined?(@@other_class)
|
25
|
-
@@other_class = make_model("other_slugged_model", :name) do |t|
|
26
|
-
t.string :name, :unique => true
|
27
|
-
t.string :slug, :unique => true
|
28
|
-
t.boolean :active, :default => true
|
29
|
-
end
|
30
|
-
@@other_class.send :include, FriendlyId::Slugged
|
31
|
-
@@other_class
|
32
|
-
end
|
12
|
+
setup { User }
|
33
13
|
|
34
|
-
|
35
|
-
klass.delete_all
|
36
|
-
other_class.delete_all
|
37
|
-
end
|
14
|
+
require File.expand_path("../shared.rb", __FILE__)
|
38
15
|
|
39
|
-
|
40
|
-
|
41
|
-
|
16
|
+
test "configuration should have a sequence_separator" do |klass|
|
17
|
+
assert !klass.friendly_id_config.sequence_separator.empty?
|
18
|
+
end
|
42
19
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
20
|
+
test "should make a new slug if the friendly_id method value has changed" do |klass|
|
21
|
+
with_instance_of klass do |record|
|
22
|
+
record.name = "Changed Value"
|
23
|
+
record.save!
|
24
|
+
assert_equal "changed-value", record.slug
|
47
25
|
end
|
26
|
+
end
|
48
27
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
assert_match(/3\z/, instance3.friendly_id)
|
28
|
+
test "should increment the slug sequence for duplicate friendly ids" do |klass|
|
29
|
+
with_instance_of klass do |record|
|
30
|
+
record2 = klass.create! :name => record.name
|
31
|
+
assert record2.friendly_id.match(/2\z/)
|
54
32
|
end
|
33
|
+
end
|
55
34
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
35
|
+
test "should not add slug sequence on update after other conflicting slugs were added" do |klass|
|
36
|
+
with_instance_of klass do |record|
|
37
|
+
old = record.friendly_id
|
38
|
+
record2 = klass.create! :name => record.name
|
39
|
+
record.save!
|
40
|
+
record.reload
|
41
|
+
assert_equal old, record.to_param
|
62
42
|
end
|
63
|
-
|
64
43
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: friendly_id4
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease: 6
|
5
|
-
version: 4.0.0.
|
5
|
+
version: 4.0.0.pre3
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Norman Clarke
|
@@ -10,8 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-06-
|
14
|
-
default_executable:
|
13
|
+
date: 2011-06-25 00:00:00 Z
|
15
14
|
dependencies:
|
16
15
|
- !ruby/object:Gem::Dependency
|
17
16
|
name: activerecord
|
@@ -25,29 +24,52 @@ dependencies:
|
|
25
24
|
type: :development
|
26
25
|
version_requirements: *id001
|
27
26
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
27
|
+
name: sqlite3
|
29
28
|
prerelease: false
|
30
29
|
requirement: &id002 !ruby/object:Gem::Requirement
|
31
30
|
none: false
|
32
31
|
requirements:
|
33
32
|
- - ~>
|
34
33
|
- !ruby/object:Gem::Version
|
35
|
-
version: "
|
34
|
+
version: "1.3"
|
36
35
|
type: :development
|
37
36
|
version_requirements: *id002
|
38
37
|
- !ruby/object:Gem::Dependency
|
39
|
-
name:
|
38
|
+
name: cutest
|
40
39
|
prerelease: false
|
41
40
|
requirement: &id003 !ruby/object:Gem::Requirement
|
42
41
|
none: false
|
43
42
|
requirements:
|
44
43
|
- - ~>
|
45
44
|
- !ruby/object:Gem::Version
|
46
|
-
version:
|
45
|
+
version: 1.1.2
|
47
46
|
type: :development
|
48
47
|
version_requirements: *id003
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: ffaker
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id004
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: yard
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: "0"
|
68
|
+
type: :development
|
69
|
+
version_requirements: *id005
|
49
70
|
description: " FriendlyId is the \"Swiss Army bulldozer\" of slugging and permalink plugins\n for Ruby on Rails. It allows you to create pretty URL's and work with\n human-friendly strings as if they were numeric ids for ActiveRecord models.\n"
|
50
|
-
email:
|
71
|
+
email:
|
72
|
+
- norman@njclarke.com
|
51
73
|
executables: []
|
52
74
|
|
53
75
|
extensions: []
|
@@ -55,20 +77,34 @@ extensions: []
|
|
55
77
|
extra_rdoc_files: []
|
56
78
|
|
57
79
|
files:
|
80
|
+
- .gitignore
|
81
|
+
- ABOUT.md
|
82
|
+
- Guide.md
|
83
|
+
- README.md
|
84
|
+
- Rakefile
|
85
|
+
- bench.rb
|
86
|
+
- friendly_id.gemspec
|
87
|
+
- lib/friendly_id.rb
|
88
|
+
- lib/friendly_id/base.rb
|
89
|
+
- lib/friendly_id/configuration.rb
|
90
|
+
- lib/friendly_id/finder_methods.rb
|
91
|
+
- lib/friendly_id/history.rb
|
92
|
+
- lib/friendly_id/migration.rb
|
93
|
+
- lib/friendly_id/model.rb
|
94
|
+
- lib/friendly_id/object_utils.rb
|
58
95
|
- lib/friendly_id/scoped.rb
|
96
|
+
- lib/friendly_id/slug_sequencer.rb
|
59
97
|
- lib/friendly_id/slugged.rb
|
60
|
-
- lib/friendly_id/test/generic.rb
|
61
|
-
- lib/friendly_id/test.rb
|
62
98
|
- lib/friendly_id/version.rb
|
63
|
-
- lib/
|
64
|
-
- README.md
|
65
|
-
- Rakefile
|
99
|
+
- lib/generators/friendly_id_generator.rb
|
66
100
|
- test/core_test.rb
|
101
|
+
- test/helper.rb
|
102
|
+
- test/history_test.rb
|
103
|
+
- test/object_utils_test.rb
|
67
104
|
- test/scoped_test.rb
|
105
|
+
- test/shared.rb
|
68
106
|
- test/slugged_test.rb
|
69
|
-
|
70
|
-
has_rdoc: true
|
71
|
-
homepage: http://norman.github.com/friendly_id_4
|
107
|
+
homepage: http://norman.github.com/friendly_id
|
72
108
|
licenses: []
|
73
109
|
|
74
110
|
post_install_message:
|
@@ -90,12 +126,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
126
|
version: 1.3.1
|
91
127
|
requirements: []
|
92
128
|
|
93
|
-
rubyforge_project:
|
94
|
-
rubygems_version: 1.
|
129
|
+
rubyforge_project: friendly_id
|
130
|
+
rubygems_version: 1.8.5
|
95
131
|
signing_key:
|
96
132
|
specification_version: 3
|
97
133
|
summary: A comprehensive slugging and pretty-URL plugin.
|
98
|
-
test_files:
|
99
|
-
|
100
|
-
- test/scoped_test.rb
|
101
|
-
- test/slugged_test.rb
|
134
|
+
test_files: []
|
135
|
+
|