friendly_id 5.5.1 → 5.7.0
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.
- checksums.yaml +4 -4
- data/Changelog.md +4 -1
- data/README.md +3 -3
- data/lib/friendly_id/history.rb +2 -2
- data/lib/friendly_id/slug_generator.rb +15 -0
- data/lib/friendly_id/slugged.rb +19 -1
- data/lib/friendly_id/version.rb +1 -1
- metadata +5 -76
- checksums.yaml.gz.sig +0 -0
- data/.gemtest +0 -0
- data/.github/FUNDING.yml +0 -1
- data/.github/dependabot.yml +0 -6
- data/.github/stale.yml +0 -17
- data/.github/workflows/test.yml +0 -62
- data/.gitignore +0 -14
- data/.yardopts +0 -8
- data/CONTRIBUTING.md +0 -11
- data/Gemfile +0 -23
- data/Rakefile +0 -104
- data/UPGRADING.md +0 -115
- data/bench.rb +0 -84
- data/certs/parndt.pem +0 -27
- data/friendly_id.gemspec +0 -36
- data/gemfiles/Gemfile.rails-5.2.rb +0 -22
- data/gemfiles/Gemfile.rails-6.0.rb +0 -22
- data/gemfiles/Gemfile.rails-6.1.rb +0 -22
- data/gemfiles/Gemfile.rails-7.0.rb +0 -22
- data/guide.rb +0 -24
- data/test/base_test.rb +0 -69
- data/test/benchmarks/finders.rb +0 -90
- data/test/benchmarks/object_utils.rb +0 -56
- data/test/candidates_test.rb +0 -142
- data/test/configuration_test.rb +0 -60
- data/test/core_test.rb +0 -35
- data/test/databases.yml +0 -22
- data/test/finders_test.rb +0 -76
- data/test/generator_test.rb +0 -38
- data/test/helper.rb +0 -125
- data/test/history_test.rb +0 -434
- data/test/numeric_slug_test.rb +0 -31
- data/test/object_utils_test.rb +0 -27
- data/test/reserved_test.rb +0 -73
- data/test/schema.rb +0 -117
- data/test/scoped_test.rb +0 -95
- data/test/sequentially_slugged_test.rb +0 -214
- data/test/shared.rb +0 -181
- data/test/simple_i18n_test.rb +0 -144
- data/test/slugged_test.rb +0 -628
- data/test/sti_test.rb +0 -135
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
data/bench.rb
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
require File.expand_path("../test/helper", __FILE__)
|
|
2
|
-
require "ffaker"
|
|
3
|
-
|
|
4
|
-
N = 10000
|
|
5
|
-
|
|
6
|
-
def transaction
|
|
7
|
-
ActiveRecord::Base.transaction do
|
|
8
|
-
yield
|
|
9
|
-
|
|
10
|
-
raise ActiveRecord::Rollback
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class Array
|
|
15
|
-
def rand
|
|
16
|
-
self[Kernel.rand(length)]
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
Book = Class.new ActiveRecord::Base
|
|
21
|
-
|
|
22
|
-
class Journalist < ActiveRecord::Base
|
|
23
|
-
extend FriendlyId
|
|
24
|
-
friendly_id :name, use: :slugged
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
class Manual < ActiveRecord::Base
|
|
28
|
-
extend FriendlyId
|
|
29
|
-
friendly_id :name, use: :history
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
class Restaurant < ActiveRecord::Base
|
|
33
|
-
extend FriendlyId
|
|
34
|
-
friendly_id :name, use: :finders
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
BOOKS = []
|
|
38
|
-
JOURNALISTS = []
|
|
39
|
-
MANUALS = []
|
|
40
|
-
RESTAURANTS = []
|
|
41
|
-
|
|
42
|
-
100.times do
|
|
43
|
-
name = FFaker::Name.name
|
|
44
|
-
BOOKS << (Book.create! name: name).id
|
|
45
|
-
JOURNALISTS << (Journalist.create! name: name).friendly_id
|
|
46
|
-
MANUALS << (Manual.create! name: name).friendly_id
|
|
47
|
-
RESTAURANTS << (Restaurant.create! name: name).friendly_id
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
ActiveRecord::Base.connection.execute "UPDATE manuals SET slug = NULL"
|
|
51
|
-
|
|
52
|
-
Benchmark.bmbm do |x|
|
|
53
|
-
x.report "find (without FriendlyId)" do
|
|
54
|
-
N.times { Book.find BOOKS.rand }
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
x.report "find (in-table slug)" do
|
|
58
|
-
N.times { Journalist.friendly.find JOURNALISTS.rand }
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
x.report "find (in-table slug; using finders module)" do
|
|
62
|
-
N.times { Restaurant.find RESTAURANTS.rand }
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
x.report "find (external slug)" do
|
|
66
|
-
N.times { Manual.friendly.find MANUALS.rand }
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
x.report "insert (without FriendlyId)" do
|
|
70
|
-
N.times { transaction { Book.create name: FFaker::Name.name } }
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
x.report "insert (in-table-slug)" do
|
|
74
|
-
N.times { transaction { Journalist.create name: FFaker::Name.name } }
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
x.report "insert (in-table-slug; using finders module)" do
|
|
78
|
-
N.times { transaction { Restaurant.create name: FFaker::Name.name } }
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
x.report "insert (external slug)" do
|
|
82
|
-
N.times { transaction { Manual.create name: FFaker::Name.name } }
|
|
83
|
-
end
|
|
84
|
-
end
|
data/certs/parndt.pem
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
-----BEGIN CERTIFICATE-----
|
|
2
|
-
MIIEljCCAv6gAwIBAgIBATANBgkqhkiG9w0BAQsFADBRMREwDwYDVQQDDAhydWJ5
|
|
3
|
-
Z2VtczERMA8GCgmSJomT8ixkARkWAXAxFTATBgoJkiaJk/IsZAEZFgVhcm5kdDES
|
|
4
|
-
MBAGCgmSJomT8ixkARkWAmlvMB4XDTIyMTExNTIyMjQzMFoXDTIzMTExNTIyMjQz
|
|
5
|
-
MFowUTERMA8GA1UEAwwIcnVieWdlbXMxETAPBgoJkiaJk/IsZAEZFgFwMRUwEwYK
|
|
6
|
-
CZImiZPyLGQBGRYFYXJuZHQxEjAQBgoJkiaJk/IsZAEZFgJpbzCCAaIwDQYJKoZI
|
|
7
|
-
hvcNAQEBBQADggGPADCCAYoCggGBAMPq2bIEO+BmmBeuidSySK7xlL/LWBHzyDxw
|
|
8
|
-
EMgWsHqJMDZYCZI4WoWbSTSSLrp5zPXLWN0hB23u3dxFp4RVygTTZkc8k05mteab
|
|
9
|
-
fdREGgdcP+mY8/ASQSvb1VW6IM51Srgjy1SK0S5Qf3HAiQafFvRsxRkY0SWyth24
|
|
10
|
-
ne/7HG667vHQ1+t0VFl8twupJE9S8p2zgX3eZBl2yRNm/kE5reUsOLvmS58Iri/X
|
|
11
|
-
9tnz0SGkzrKkim9OIByq7XkFLL3oaIyfbBVgOWilM5pvxj/xNuRH7EIM6aE3q0UZ
|
|
12
|
-
xo7o9u9Iz2zApDEjejByPjxWAhLuP3v3bJyinRFE1rO47lEM/s6KM/6YooxvgYIN
|
|
13
|
-
miYYFRtTj9nmKEMv6+h1mZ1/ZwqStTTRh/T90T65dcgsoqRd0JNvpNRjFrYH5cuj
|
|
14
|
-
QZWMl/FE6AADm0GXa34ZiTQx3Wx2ctqJLFak8+imPwes90nCpiYmgaZpwBI+shjU
|
|
15
|
-
AddbPDNq+EoxPMWTh0Er3w76fywOWQIDAQABo3kwdzAJBgNVHRMEAjAAMAsGA1Ud
|
|
16
|
-
DwQEAwIEsDAdBgNVHQ4EFgQUxRJaTQZmtkN8FKUWVHKc2riND18wHgYDVR0RBBcw
|
|
17
|
-
FYETcnVieWdlbXNAcC5hcm5kdC5pbzAeBgNVHRIEFzAVgRNydWJ5Z2Vtc0BwLmFy
|
|
18
|
-
bmR0LmlvMA0GCSqGSIb3DQEBCwUAA4IBgQBSRGMkZ2dvJ0LSjFz+rIt3G3AZMbKD
|
|
19
|
-
tjaaQRuC9rOkrl3Rml6h9j7cHYiM0wkTjXneFNySc8jWmM/jKnxiiUfUK9r1XL4n
|
|
20
|
-
71tz39+MD2lIpLVVEQ69MIoUseppNUTCg0mNghSDYNwISMD/hoWwbJudBi56DbhE
|
|
21
|
-
xkulLbw8qtcEE+iilIKibe+eJF4platKScsOA7d1AuilR1/S245UzeqwwyI52/xK
|
|
22
|
-
dfoP928X9Tb/48+83lWUgAgCQOd6WdfCpgQ5H6R90lc8L7OfuDR/vgcmSOTsNVgG
|
|
23
|
-
1TC3b2FISS0p0qfZsiS7BXh+ARoBKLXsV1a7WR36X0dUpajvk+zzBGrFCdbW43Gx
|
|
24
|
-
wmJzIksYnf9Ktg8Ux+FLcRBGw4qEIyWvqmS0obB1Hke68rTg0uNTFcKXsNw33XF5
|
|
25
|
-
fw1cbj95g7OPe0feGK8+afXh/L38vx/hIIOGlUEZ+HaWL2Dki/7vRGvda8dfOpG5
|
|
26
|
-
bJfaoyKbVsrK+gGKFJv860zsO8lg6BGLsUw=
|
|
27
|
-
-----END CERTIFICATE-----
|
data/friendly_id.gemspec
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
require File.expand_path("../lib/friendly_id/version", __FILE__)
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |s|
|
|
4
|
-
s.name = "friendly_id"
|
|
5
|
-
s.version = FriendlyId::VERSION
|
|
6
|
-
s.authors = ["Norman Clarke", "Philip Arndt"]
|
|
7
|
-
s.email = ["norman@njclarke.com", "p@arndt.io"]
|
|
8
|
-
s.homepage = "https://github.com/norman/friendly_id"
|
|
9
|
-
s.summary = "A comprehensive slugging and pretty-URL plugin."
|
|
10
|
-
s.files = `git ls-files`.split("\n")
|
|
11
|
-
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
|
12
|
-
s.require_paths = ["lib"]
|
|
13
|
-
s.license = "MIT"
|
|
14
|
-
|
|
15
|
-
s.required_ruby_version = ">= 2.1.0"
|
|
16
|
-
|
|
17
|
-
s.add_dependency "activerecord", ">= 4.0.0"
|
|
18
|
-
|
|
19
|
-
s.add_development_dependency "coveralls"
|
|
20
|
-
s.add_development_dependency "railties", ">= 4.0"
|
|
21
|
-
s.add_development_dependency "minitest", "~> 5.3"
|
|
22
|
-
s.add_development_dependency "mocha", "~> 2.1"
|
|
23
|
-
s.add_development_dependency "yard"
|
|
24
|
-
s.add_development_dependency "i18n"
|
|
25
|
-
s.add_development_dependency "ffaker"
|
|
26
|
-
s.add_development_dependency "simplecov"
|
|
27
|
-
|
|
28
|
-
s.description = "FriendlyId is the \"Swiss Army bulldozer\" of slugging " \
|
|
29
|
-
"and permalink plugins for Active Record. It lets you create pretty URLs " \
|
|
30
|
-
"and work with human-friendly strings as if they were numeric ids."
|
|
31
|
-
|
|
32
|
-
s.cert_chain = [File.expand_path("certs/parndt.pem", __dir__)]
|
|
33
|
-
if $PROGRAM_NAME.end_with?("gem") && ARGV.include?("build") && ARGV.include?(__FILE__)
|
|
34
|
-
s.signing_key = File.expand_path("~/.ssh/gem-private_key.pem")
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
source "https://rubygems.org"
|
|
2
|
-
|
|
3
|
-
gemspec path: "../"
|
|
4
|
-
|
|
5
|
-
gem "activerecord", "~> 5.2.0"
|
|
6
|
-
gem "railties", "~> 5.2.0"
|
|
7
|
-
|
|
8
|
-
# Database Configuration
|
|
9
|
-
group :development, :test do
|
|
10
|
-
platforms :jruby do
|
|
11
|
-
gem "activerecord-jdbcmysql-adapter", "~> 51.1"
|
|
12
|
-
gem "activerecord-jdbcpostgresql-adapter", "~> 51.1"
|
|
13
|
-
gem "kramdown"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
platforms :ruby, :rbx do
|
|
17
|
-
gem "sqlite3"
|
|
18
|
-
gem "mysql2"
|
|
19
|
-
gem "pg"
|
|
20
|
-
gem "redcarpet"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
source "https://rubygems.org"
|
|
2
|
-
|
|
3
|
-
gemspec path: "../"
|
|
4
|
-
|
|
5
|
-
gem "activerecord", "~> 6.0.0"
|
|
6
|
-
gem "railties", "~> 6.0.0"
|
|
7
|
-
|
|
8
|
-
# Database Configuration
|
|
9
|
-
group :development, :test do
|
|
10
|
-
platforms :jruby do
|
|
11
|
-
gem "activerecord-jdbcmysql-adapter", "~> 51.1"
|
|
12
|
-
gem "activerecord-jdbcpostgresql-adapter", "~> 51.1"
|
|
13
|
-
gem "kramdown"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
platforms :ruby, :rbx do
|
|
17
|
-
gem "sqlite3"
|
|
18
|
-
gem "mysql2"
|
|
19
|
-
gem "pg"
|
|
20
|
-
gem "redcarpet"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
source "https://rubygems.org"
|
|
2
|
-
|
|
3
|
-
gemspec path: "../"
|
|
4
|
-
|
|
5
|
-
gem "activerecord", "~> 6.1.4"
|
|
6
|
-
gem "railties", "~> 6.1.4"
|
|
7
|
-
|
|
8
|
-
# Database Configuration
|
|
9
|
-
group :development, :test do
|
|
10
|
-
platforms :jruby do
|
|
11
|
-
gem "activerecord-jdbcmysql-adapter", "~> 61.0"
|
|
12
|
-
gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
|
|
13
|
-
gem "kramdown"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
platforms :ruby, :rbx do
|
|
17
|
-
gem "sqlite3"
|
|
18
|
-
gem "mysql2"
|
|
19
|
-
gem "pg"
|
|
20
|
-
gem "redcarpet"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
source "https://rubygems.org"
|
|
2
|
-
|
|
3
|
-
gemspec path: "../"
|
|
4
|
-
|
|
5
|
-
gem "activerecord", "~> 7.0.0"
|
|
6
|
-
gem "railties", "~> 7.0.0"
|
|
7
|
-
|
|
8
|
-
# Database Configuration
|
|
9
|
-
group :development, :test do
|
|
10
|
-
platforms :jruby do
|
|
11
|
-
gem "activerecord-jdbcmysql-adapter", "~> 61.0"
|
|
12
|
-
gem "activerecord-jdbcpostgresql-adapter", "~> 61.0"
|
|
13
|
-
gem "kramdown"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
platforms :ruby, :rbx do
|
|
17
|
-
gem "sqlite3"
|
|
18
|
-
gem "mysql2"
|
|
19
|
-
gem "pg"
|
|
20
|
-
gem "redcarpet"
|
|
21
|
-
end
|
|
22
|
-
end
|
data/guide.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
|
|
3
|
-
# This script generates the Guide.md file included in the Yard docs.
|
|
4
|
-
|
|
5
|
-
def comments_from path
|
|
6
|
-
path = File.expand_path("../lib/friendly_id/#{path}", __FILE__)
|
|
7
|
-
matches = File.read(path).match(/\n\s*# @guide begin\n(.*)\s*# @guide end/m)
|
|
8
|
-
|
|
9
|
-
return if matches.nil?
|
|
10
|
-
|
|
11
|
-
match = matches[1].to_s
|
|
12
|
-
match.split("\n")
|
|
13
|
-
.map { |x| x.sub(/^\s*#\s?/, "") } # Strip off the comment, leading whitespace, and the space after the comment
|
|
14
|
-
.reject { |x| x =~ /^@/ } # Ignore yarddoc tags for the guide
|
|
15
|
-
.join("\n").strip
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
File.open(File.expand_path("../Guide.md", __FILE__), "w:utf-8") do |guide|
|
|
19
|
-
["../friendly_id.rb", "base.rb", "finders.rb", "slugged.rb", "history.rb",
|
|
20
|
-
"scoped.rb", "simple_i18n.rb", "reserved.rb"].each do |file|
|
|
21
|
-
guide.write comments_from file
|
|
22
|
-
guide.write "\n"
|
|
23
|
-
end
|
|
24
|
-
end
|
data/test/base_test.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
require "helper"
|
|
2
|
-
|
|
3
|
-
class CoreTest < TestCaseClass
|
|
4
|
-
include FriendlyId::Test
|
|
5
|
-
|
|
6
|
-
test "friendly_id can be added using 'extend'" do
|
|
7
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
8
|
-
extend FriendlyId
|
|
9
|
-
end
|
|
10
|
-
assert klass.respond_to? :friendly_id
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
test "friendly_id can be added using 'include'" do
|
|
14
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
15
|
-
include FriendlyId
|
|
16
|
-
end
|
|
17
|
-
assert klass.respond_to? :friendly_id
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
test "friendly_id should accept a base and a hash" do
|
|
21
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
22
|
-
self.abstract_class = true
|
|
23
|
-
extend FriendlyId
|
|
24
|
-
friendly_id :foo, use: :slugged, slug_column: :bar
|
|
25
|
-
end
|
|
26
|
-
assert klass < FriendlyId::Slugged
|
|
27
|
-
assert_equal :foo, klass.friendly_id_config.base
|
|
28
|
-
assert_equal :bar, klass.friendly_id_config.slug_column
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
test "friendly_id should accept a block" do
|
|
32
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
33
|
-
self.abstract_class = true
|
|
34
|
-
extend FriendlyId
|
|
35
|
-
friendly_id :foo do |config|
|
|
36
|
-
config.use :slugged
|
|
37
|
-
config.base = :foo
|
|
38
|
-
config.slug_column = :bar
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
assert klass < FriendlyId::Slugged
|
|
42
|
-
assert_equal :foo, klass.friendly_id_config.base
|
|
43
|
-
assert_equal :bar, klass.friendly_id_config.slug_column
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
test "the block passed to friendly_id should be evaluated before arguments" do
|
|
47
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
48
|
-
self.abstract_class = true
|
|
49
|
-
extend FriendlyId
|
|
50
|
-
friendly_id :foo do |config|
|
|
51
|
-
config.base = :bar
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
assert_equal :foo, klass.friendly_id_config.base
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
test "should allow defaults to be set via a block" do
|
|
58
|
-
FriendlyId.defaults do |config|
|
|
59
|
-
config.base = :foo
|
|
60
|
-
end
|
|
61
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
62
|
-
self.abstract_class = true
|
|
63
|
-
extend FriendlyId
|
|
64
|
-
end
|
|
65
|
-
assert_equal :foo, klass.friendly_id_config.base
|
|
66
|
-
ensure
|
|
67
|
-
FriendlyId.instance_variable_set :@defaults, nil
|
|
68
|
-
end
|
|
69
|
-
end
|
data/test/benchmarks/finders.rb
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
require File.expand_path("../../helper", __FILE__)
|
|
2
|
-
require "ffaker"
|
|
3
|
-
|
|
4
|
-
# This benchmark tests ActiveRecord and FriendlyId methods for performing a find
|
|
5
|
-
#
|
|
6
|
-
# ActiveRecord: where.first 8.970000 0.040000 9.010000 ( 9.029544)
|
|
7
|
-
# ActiveRecord: where.take 8.100000 0.030000 8.130000 ( 8.157024)
|
|
8
|
-
# ActiveRecord: find 2.720000 0.010000 2.730000 ( 2.733527)
|
|
9
|
-
# ActiveRecord: find_by(:id) 2.920000 0.000000 2.920000 ( 2.926318)
|
|
10
|
-
# ActiveRecord: find_by(:slug) 2.650000 0.020000 2.670000 ( 2.662677)
|
|
11
|
-
# FriendlyId: find (in-table slug w/ finders) 9.820000 0.030000 9.850000 ( 9.873358)
|
|
12
|
-
# FriendlyId: friendly.find (in-table slug) 12.890000 0.050000 12.940000 ( 12.951156)
|
|
13
|
-
|
|
14
|
-
N = 50000
|
|
15
|
-
|
|
16
|
-
def transaction
|
|
17
|
-
ActiveRecord::Base.transaction do
|
|
18
|
-
yield
|
|
19
|
-
|
|
20
|
-
raise ActiveRecord::Rollback
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
class Array
|
|
25
|
-
def rand
|
|
26
|
-
self[Kernel.rand(length)]
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
Book = Class.new ActiveRecord::Base
|
|
31
|
-
|
|
32
|
-
class Journalist < ActiveRecord::Base
|
|
33
|
-
extend FriendlyId
|
|
34
|
-
friendly_id :name, use: :slugged
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
class Manual < ActiveRecord::Base
|
|
38
|
-
extend FriendlyId
|
|
39
|
-
friendly_id :name, use: :history
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
class Restaurant < ActiveRecord::Base
|
|
43
|
-
extend FriendlyId
|
|
44
|
-
friendly_id :name, use: :finders
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
BOOKS = []
|
|
48
|
-
JOURNALISTS = []
|
|
49
|
-
MANUALS = []
|
|
50
|
-
RESTAURANTS = []
|
|
51
|
-
|
|
52
|
-
100.times do
|
|
53
|
-
name = FFaker::Name.name
|
|
54
|
-
BOOKS << (Book.create! name: name).id
|
|
55
|
-
JOURNALISTS << (Journalist.create! name: name).friendly_id
|
|
56
|
-
MANUALS << (Manual.create! name: name).friendly_id
|
|
57
|
-
RESTAURANTS << (Restaurant.create! name: name).friendly_id
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
ActiveRecord::Base.connection.execute "UPDATE manuals SET slug = NULL"
|
|
61
|
-
|
|
62
|
-
Benchmark.bmbm do |x|
|
|
63
|
-
x.report "ActiveRecord: where.first" do
|
|
64
|
-
N.times { Book.where(id: BOOKS.rand).first }
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
x.report "ActiveRecord: where.take" do
|
|
68
|
-
N.times { Book.where(id: BOOKS.rand).take }
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
x.report "ActiveRecord: find" do
|
|
72
|
-
N.times { Book.find BOOKS.rand }
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
x.report "ActiveRecord: find_by(:id)" do
|
|
76
|
-
N.times { Book.find_by(id: BOOKS.rand) }
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
x.report "ActiveRecord: find_by(:slug)" do
|
|
80
|
-
N.times { Restaurant.find_by(slug: RESTAURANTS.rand) }
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
x.report "FriendlyId: find (in-table slug w/ finders)" do
|
|
84
|
-
N.times { Restaurant.find RESTAURANTS.rand }
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
x.report "FriendlyId: friendly.find (in-table slug)" do
|
|
88
|
-
N.times { Restaurant.friendly.find RESTAURANTS.rand }
|
|
89
|
-
end
|
|
90
|
-
end
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require File.expand_path("../../helper", __FILE__)
|
|
2
|
-
|
|
3
|
-
# This benchmark compares the timings of the friendly_id? and unfriendly_id? on various objects
|
|
4
|
-
#
|
|
5
|
-
# integer friendly_id? 6.370000 0.000000 6.370000 ( 6.380925)
|
|
6
|
-
# integer unfriendly_id? 6.640000 0.010000 6.650000 ( 6.646057)
|
|
7
|
-
# AR::Base friendly_id? 2.340000 0.000000 2.340000 ( 2.340743)
|
|
8
|
-
# AR::Base unfriendly_id? 2.560000 0.000000 2.560000 ( 2.560039)
|
|
9
|
-
# hash friendly_id? 5.090000 0.010000 5.100000 ( 5.097662)
|
|
10
|
-
# hash unfriendly_id? 5.430000 0.000000 5.430000 ( 5.437160)
|
|
11
|
-
# nil friendly_id? 5.610000 0.010000 5.620000 ( 5.611487)
|
|
12
|
-
# nil unfriendly_id? 5.870000 0.000000 5.870000 ( 5.880484)
|
|
13
|
-
# numeric string friendly_id? 9.270000 0.030000 9.300000 ( 9.308452)
|
|
14
|
-
# numeric string unfriendly_id? 9.190000 0.040000 9.230000 ( 9.252890)
|
|
15
|
-
# test_string friendly_id? 8.380000 0.010000 8.390000 ( 8.411762)
|
|
16
|
-
# test_string unfriendly_id? 8.450000 0.010000 8.460000 ( 8.463662)
|
|
17
|
-
|
|
18
|
-
# From the ObjectUtils docs...
|
|
19
|
-
# 123.friendly_id? #=> false
|
|
20
|
-
# :id.friendly_id? #=> false
|
|
21
|
-
# {:name => 'joe'}.friendly_id? #=> false
|
|
22
|
-
# ['name = ?', 'joe'].friendly_id? #=> false
|
|
23
|
-
# nil.friendly_id? #=> false
|
|
24
|
-
# "123".friendly_id? #=> nil
|
|
25
|
-
# "abc123".friendly_id? #=> true
|
|
26
|
-
|
|
27
|
-
Book = Class.new ActiveRecord::Base
|
|
28
|
-
|
|
29
|
-
test_integer = 123
|
|
30
|
-
test_active_record_object = Book.new
|
|
31
|
-
test_hash = {name: "joe"}
|
|
32
|
-
test_nil = nil
|
|
33
|
-
test_numeric_string = "123"
|
|
34
|
-
test_string = "abc123"
|
|
35
|
-
|
|
36
|
-
N = 5_000_000
|
|
37
|
-
|
|
38
|
-
Benchmark.bmbm do |x|
|
|
39
|
-
x.report("integer friendly_id?") { N.times { test_integer.friendly_id? } }
|
|
40
|
-
x.report("integer unfriendly_id?") { N.times { test_integer.unfriendly_id? } }
|
|
41
|
-
|
|
42
|
-
x.report("AR::Base friendly_id?") { N.times { test_active_record_object.friendly_id? } }
|
|
43
|
-
x.report("AR::Base unfriendly_id?") { N.times { test_active_record_object.unfriendly_id? } }
|
|
44
|
-
|
|
45
|
-
x.report("hash friendly_id?") { N.times { test_hash.friendly_id? } }
|
|
46
|
-
x.report("hash unfriendly_id?") { N.times { test_hash.unfriendly_id? } }
|
|
47
|
-
|
|
48
|
-
x.report("nil friendly_id?") { N.times { test_nil.friendly_id? } }
|
|
49
|
-
x.report("nil unfriendly_id?") { N.times { test_nil.unfriendly_id? } }
|
|
50
|
-
|
|
51
|
-
x.report("numeric string friendly_id?") { N.times { test_numeric_string.friendly_id? } }
|
|
52
|
-
x.report("numeric string unfriendly_id?") { N.times { test_numeric_string.unfriendly_id? } }
|
|
53
|
-
|
|
54
|
-
x.report("test_string friendly_id?") { N.times { test_string.friendly_id? } }
|
|
55
|
-
x.report("test_string unfriendly_id?") { N.times { test_string.unfriendly_id? } }
|
|
56
|
-
end
|
data/test/candidates_test.rb
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
require "helper"
|
|
2
|
-
|
|
3
|
-
class CandidatesTest < TestCaseClass
|
|
4
|
-
include FriendlyId::Test
|
|
5
|
-
|
|
6
|
-
class Airport
|
|
7
|
-
def initialize(code)
|
|
8
|
-
@code = code
|
|
9
|
-
end
|
|
10
|
-
attr_reader :code
|
|
11
|
-
alias_method :to_s, :code
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
class City < ActiveRecord::Base
|
|
15
|
-
extend FriendlyId
|
|
16
|
-
friendly_id :slug_candidates, use: :slugged
|
|
17
|
-
alias_attribute :slug_candidates, :name
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def model_class
|
|
21
|
-
City
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def with_instances_of(klass = model_class, &block)
|
|
25
|
-
transaction do
|
|
26
|
-
city1 = klass.create! name: "New York", code: "JFK"
|
|
27
|
-
city2 = klass.create! name: "New York", code: "EWR"
|
|
28
|
-
yield city1, city2
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
alias_method :with_instances, :with_instances_of
|
|
32
|
-
|
|
33
|
-
test "resolves conflict with candidate" do
|
|
34
|
-
with_instances do |city1, city2|
|
|
35
|
-
assert_equal "new-york", city1.slug
|
|
36
|
-
assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city2.slug)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
test "accepts candidate as symbol" do
|
|
41
|
-
klass = Class.new model_class do
|
|
42
|
-
def slug_candidates
|
|
43
|
-
:name
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
with_instances_of klass do |_, city|
|
|
47
|
-
assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
test "accepts multiple candidates" do
|
|
52
|
-
klass = Class.new model_class do
|
|
53
|
-
def slug_candidates
|
|
54
|
-
[name, code]
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
with_instances_of klass do |_, city|
|
|
58
|
-
assert_equal "ewr", city.slug
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
test "ignores blank candidate" do
|
|
63
|
-
klass = Class.new model_class do
|
|
64
|
-
def slug_candidates
|
|
65
|
-
[name, ""]
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
with_instances_of klass do |_, city|
|
|
69
|
-
assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
test "ignores nil candidate" do
|
|
74
|
-
klass = Class.new model_class do
|
|
75
|
-
def slug_candidates
|
|
76
|
-
[name, nil]
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
with_instances_of klass do |_, city|
|
|
80
|
-
assert_match(/\Anew-york-([a-z0-9]+-){4}[a-z0-9]+\z/, city.slug)
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
test "accepts candidate with nested array" do
|
|
85
|
-
klass = Class.new model_class do
|
|
86
|
-
def slug_candidates
|
|
87
|
-
[name, [name, code]]
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
with_instances_of klass do |_, city|
|
|
91
|
-
assert_equal "new-york-ewr", city.slug
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
test "accepts candidate with lambda" do
|
|
96
|
-
klass = Class.new City do
|
|
97
|
-
def slug_candidates
|
|
98
|
-
[name, [name, -> { rand 1000 }]]
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
with_instances_of klass do |_, city|
|
|
102
|
-
assert_match(/\Anew-york-\d{,3}\z/, city.friendly_id)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
test "accepts candidate with object" do
|
|
107
|
-
klass = Class.new City do
|
|
108
|
-
def slug_candidates
|
|
109
|
-
[name, [name, Airport.new(code)]]
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
with_instances_of klass do |_, city|
|
|
113
|
-
assert_equal "new-york-ewr", city.friendly_id
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
test "allows to iterate through candidates without passing block" do
|
|
118
|
-
klass = Class.new model_class do
|
|
119
|
-
def slug_candidates
|
|
120
|
-
:name
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
with_instances_of klass do |_, city|
|
|
124
|
-
candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
|
|
125
|
-
assert_equal candidates.each, ["new-york"]
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
test "iterates through candidates with passed block" do
|
|
130
|
-
klass = Class.new model_class do
|
|
131
|
-
def slug_candidates
|
|
132
|
-
:name
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
with_instances_of klass do |_, city|
|
|
136
|
-
collected_candidates = []
|
|
137
|
-
candidates = FriendlyId::Candidates.new(city, city.slug_candidates)
|
|
138
|
-
candidates.each { |candidate| collected_candidates << candidate }
|
|
139
|
-
assert_equal collected_candidates, ["new-york"]
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
end
|
data/test/configuration_test.rb
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
require "helper"
|
|
2
|
-
|
|
3
|
-
class ConfigurationTest < TestCaseClass
|
|
4
|
-
include FriendlyId::Test
|
|
5
|
-
|
|
6
|
-
def setup
|
|
7
|
-
@model_class = Class.new(ActiveRecord::Base) do
|
|
8
|
-
self.abstract_class = true
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
test "should set model class on initialization" do
|
|
13
|
-
config = FriendlyId::Configuration.new @model_class
|
|
14
|
-
assert_equal @model_class, config.model_class
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "should set options on initialization if present" do
|
|
18
|
-
config = FriendlyId::Configuration.new @model_class, base: "hello"
|
|
19
|
-
assert_equal "hello", config.base
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
test "should raise error if passed unrecognized option" do
|
|
23
|
-
assert_raises NoMethodError do
|
|
24
|
-
FriendlyId::Configuration.new @model_class, foo: "bar"
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
test "#use should accept a name that resolves to a module" do
|
|
29
|
-
refute @model_class < FriendlyId::Slugged
|
|
30
|
-
@model_class.class_eval do
|
|
31
|
-
extend FriendlyId
|
|
32
|
-
friendly_id :hello, use: :slugged
|
|
33
|
-
end
|
|
34
|
-
assert @model_class < FriendlyId::Slugged
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
test "#use should accept a module" do
|
|
38
|
-
my_module = Module.new
|
|
39
|
-
refute @model_class < my_module
|
|
40
|
-
@model_class.class_eval do
|
|
41
|
-
extend FriendlyId
|
|
42
|
-
friendly_id :hello, use: my_module
|
|
43
|
-
end
|
|
44
|
-
assert @model_class < my_module
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
test "#base should optionally set a value" do
|
|
48
|
-
config = FriendlyId::Configuration.new @model_class
|
|
49
|
-
assert_nil config.base
|
|
50
|
-
config.base = "foo"
|
|
51
|
-
assert_equal "foo", config.base
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
test "#base can set the value to nil" do
|
|
55
|
-
config = FriendlyId::Configuration.new @model_class
|
|
56
|
-
config.base "foo"
|
|
57
|
-
config.base nil
|
|
58
|
-
assert_nil config.base
|
|
59
|
-
end
|
|
60
|
-
end
|