friendly_id 5.4.0 → 5.5.1
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
- checksums.yaml.gz.sig +0 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/dependabot.yml +6 -0
- data/.github/stale.yml +1 -1
- data/.github/workflows/test.yml +38 -36
- data/.yardopts +2 -0
- data/Changelog.md +19 -0
- data/Gemfile +9 -13
- data/README.md +31 -8
- data/Rakefile +24 -27
- data/bench.rb +30 -27
- data/certs/parndt.pem +25 -23
- data/friendly_id.gemspec +26 -29
- data/gemfiles/Gemfile.rails-5.2.rb +11 -16
- data/gemfiles/Gemfile.rails-6.0.rb +11 -16
- data/gemfiles/Gemfile.rails-6.1.rb +22 -0
- data/gemfiles/Gemfile.rails-7.0.rb +22 -0
- data/guide.rb +13 -6
- data/lib/friendly_id/base.rb +59 -60
- data/lib/friendly_id/candidates.rb +9 -11
- data/lib/friendly_id/configuration.rb +6 -7
- data/lib/friendly_id/finder_methods.rb +63 -15
- data/lib/friendly_id/finders.rb +66 -66
- data/lib/friendly_id/history.rb +62 -63
- data/lib/friendly_id/initializer.rb +4 -4
- data/lib/friendly_id/migration.rb +6 -6
- data/lib/friendly_id/object_utils.rb +2 -2
- data/lib/friendly_id/reserved.rb +30 -32
- data/lib/friendly_id/scoped.rb +99 -102
- data/lib/friendly_id/sequentially_slugged/calculator.rb +69 -0
- data/lib/friendly_id/sequentially_slugged.rb +17 -64
- data/lib/friendly_id/simple_i18n.rb +78 -69
- data/lib/friendly_id/slug.rb +1 -2
- data/lib/friendly_id/slug_generator.rb +1 -3
- data/lib/friendly_id/slugged.rb +238 -239
- data/lib/friendly_id/version.rb +1 -1
- data/lib/friendly_id.rb +47 -49
- data/lib/generators/friendly_id_generator.rb +9 -9
- data/test/base_test.rb +10 -13
- data/test/benchmarks/finders.rb +28 -26
- data/test/benchmarks/object_utils.rb +13 -13
- data/test/candidates_test.rb +17 -18
- data/test/configuration_test.rb +7 -11
- data/test/core_test.rb +1 -2
- data/test/databases.yml +4 -3
- data/test/finders_test.rb +36 -13
- data/test/generator_test.rb +16 -26
- data/test/helper.rb +31 -24
- data/test/history_test.rb +70 -74
- data/test/numeric_slug_test.rb +4 -4
- data/test/object_utils_test.rb +0 -2
- data/test/reserved_test.rb +9 -11
- data/test/schema.rb +5 -4
- data/test/scoped_test.rb +18 -20
- data/test/sequentially_slugged_test.rb +65 -50
- data/test/shared.rb +15 -16
- data/test/simple_i18n_test.rb +22 -12
- data/test/slugged_test.rb +125 -113
- data/test/sti_test.rb +19 -21
- data.tar.gz.sig +0 -0
- metadata +38 -34
- metadata.gz.sig +0 -0
- data/gemfiles/Gemfile.rails-5.0.rb +0 -28
- data/gemfiles/Gemfile.rails-5.1.rb +0 -27
data/test/slugged_test.rb
CHANGED
@@ -2,25 +2,24 @@ require "helper"
|
|
2
2
|
|
3
3
|
class Journalist < ActiveRecord::Base
|
4
4
|
extend FriendlyId
|
5
|
-
friendly_id :name, :
|
5
|
+
friendly_id :name, use: :slugged
|
6
6
|
end
|
7
7
|
|
8
8
|
class Article < ActiveRecord::Base
|
9
9
|
extend FriendlyId
|
10
|
-
friendly_id :name, :
|
10
|
+
friendly_id :name, use: :slugged
|
11
11
|
end
|
12
12
|
|
13
13
|
class Novelist < ActiveRecord::Base
|
14
14
|
extend FriendlyId
|
15
|
-
friendly_id :name, :
|
15
|
+
friendly_id :name, use: :slugged, sequence_separator: "_"
|
16
16
|
|
17
17
|
def normalize_friendly_id(string)
|
18
|
-
super.
|
18
|
+
super.tr("-", "_")
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
class SluggedTest < TestCaseClass
|
23
|
-
|
24
23
|
include FriendlyId::Test
|
25
24
|
include FriendlyId::Test::Shared::Core
|
26
25
|
include FriendlyId::Test::Shared::Slugged
|
@@ -33,13 +32,13 @@ class SluggedTest < TestCaseClass
|
|
33
32
|
model_class = Class.new(ActiveRecord::Base) do
|
34
33
|
self.table_name = "articles"
|
35
34
|
extend FriendlyId
|
36
|
-
friendly_id :name, :
|
37
|
-
validates_length_of :slug, :
|
35
|
+
friendly_id :name, use: :slugged
|
36
|
+
validates_length_of :slug, maximum: 1
|
38
37
|
def self.name
|
39
38
|
"Article"
|
40
39
|
end
|
41
40
|
end
|
42
|
-
instance = model_class.new :
|
41
|
+
instance = model_class.new name: "hello"
|
43
42
|
refute instance.valid?
|
44
43
|
end
|
45
44
|
|
@@ -55,21 +54,21 @@ class SluggedTest < TestCaseClass
|
|
55
54
|
model_class = Class.new(ActiveRecord::Base) do
|
56
55
|
self.table_name = "journalists"
|
57
56
|
extend FriendlyId
|
58
|
-
friendly_id :name, :
|
57
|
+
friendly_id :name, use: :slugged
|
59
58
|
validates_uniqueness_of :slug_en
|
60
59
|
def self.name
|
61
60
|
"Journalist"
|
62
61
|
end
|
63
62
|
end
|
64
63
|
transaction do
|
65
|
-
instance = model_class.create! :
|
66
|
-
instance2 = model_class.create :
|
64
|
+
instance = model_class.create! name: "hello", slug_en: "hello"
|
65
|
+
instance2 = model_class.create name: "hello", slug_en: "hello"
|
67
66
|
assert instance.valid?
|
68
67
|
refute instance2.valid?
|
69
68
|
end
|
70
69
|
end
|
71
70
|
|
72
|
-
test
|
71
|
+
test "should allow a record to reuse its own slug" do
|
73
72
|
with_instance_of(model_class) do |record|
|
74
73
|
old_id = record.friendly_id
|
75
74
|
record.slug = nil
|
@@ -95,7 +94,7 @@ class SluggedTest < TestCaseClass
|
|
95
94
|
test "should set slug on create if unrelated validations fail" do
|
96
95
|
klass = Class.new model_class do
|
97
96
|
validates_presence_of :active
|
98
|
-
friendly_id :name, :
|
97
|
+
friendly_id :name, use: :slugged
|
99
98
|
|
100
99
|
def self.name
|
101
100
|
"Journalist"
|
@@ -103,18 +102,18 @@ class SluggedTest < TestCaseClass
|
|
103
102
|
end
|
104
103
|
|
105
104
|
transaction do
|
106
|
-
instance = klass.new :
|
105
|
+
instance = klass.new name: "foo"
|
107
106
|
refute instance.save
|
108
107
|
refute instance.valid?
|
109
|
-
assert_equal
|
108
|
+
assert_equal "foo", instance.slug
|
110
109
|
end
|
111
110
|
end
|
112
111
|
|
113
112
|
test "should not set slug on create if slug validation fails" do
|
114
113
|
klass = Class.new model_class do
|
115
114
|
validates_presence_of :active
|
116
|
-
validates_length_of :slug, :
|
117
|
-
friendly_id :name, :
|
115
|
+
validates_length_of :slug, minimum: 2
|
116
|
+
friendly_id :name, use: :slugged
|
118
117
|
|
119
118
|
def self.name
|
120
119
|
"Journalist"
|
@@ -122,7 +121,7 @@ class SluggedTest < TestCaseClass
|
|
122
121
|
end
|
123
122
|
|
124
123
|
transaction do
|
125
|
-
instance = klass.new :
|
124
|
+
instance = klass.new name: "x"
|
126
125
|
refute instance.save
|
127
126
|
refute instance.valid?
|
128
127
|
assert_nil instance.slug
|
@@ -131,10 +130,10 @@ class SluggedTest < TestCaseClass
|
|
131
130
|
|
132
131
|
test "should set slug on create if unrelated validations fail with custom slug_column" do
|
133
132
|
klass = Class.new(ActiveRecord::Base) do
|
134
|
-
self.table_name =
|
133
|
+
self.table_name = "authors"
|
135
134
|
extend FriendlyId
|
136
135
|
validates_presence_of :active
|
137
|
-
friendly_id :name, :
|
136
|
+
friendly_id :name, use: :slugged, slug_column: :subdomain
|
138
137
|
|
139
138
|
def self.name
|
140
139
|
"Author"
|
@@ -142,19 +141,19 @@ class SluggedTest < TestCaseClass
|
|
142
141
|
end
|
143
142
|
|
144
143
|
transaction do
|
145
|
-
instance = klass.new :
|
144
|
+
instance = klass.new name: "foo"
|
146
145
|
refute instance.save
|
147
146
|
refute instance.valid?
|
148
|
-
assert_equal
|
147
|
+
assert_equal "foo", instance.subdomain
|
149
148
|
end
|
150
149
|
end
|
151
150
|
|
152
151
|
test "should not set slug on create if custom slug column validations fail" do
|
153
152
|
klass = Class.new(ActiveRecord::Base) do
|
154
|
-
self.table_name =
|
153
|
+
self.table_name = "authors"
|
155
154
|
extend FriendlyId
|
156
|
-
validates_length_of :subdomain, :
|
157
|
-
friendly_id :name, :
|
155
|
+
validates_length_of :subdomain, minimum: 2
|
156
|
+
friendly_id :name, use: :slugged, slug_column: :subdomain
|
158
157
|
|
159
158
|
def self.name
|
160
159
|
"Author"
|
@@ -162,7 +161,7 @@ class SluggedTest < TestCaseClass
|
|
162
161
|
end
|
163
162
|
|
164
163
|
transaction do
|
165
|
-
instance = klass.new :
|
164
|
+
instance = klass.new name: "x"
|
166
165
|
refute instance.save
|
167
166
|
refute instance.valid?
|
168
167
|
assert_nil instance.subdomain
|
@@ -172,7 +171,7 @@ class SluggedTest < TestCaseClass
|
|
172
171
|
test "should keep new slug on save if unrelated validations fail" do
|
173
172
|
klass = Class.new model_class do
|
174
173
|
validates_presence_of :active
|
175
|
-
friendly_id :name, :
|
174
|
+
friendly_id :name, use: :slugged
|
176
175
|
|
177
176
|
def self.name
|
178
177
|
"Journalist"
|
@@ -180,22 +179,22 @@ class SluggedTest < TestCaseClass
|
|
180
179
|
end
|
181
180
|
|
182
181
|
transaction do
|
183
|
-
instance = klass.new :
|
182
|
+
instance = klass.new name: "foo", active: true
|
184
183
|
assert instance.save
|
185
184
|
assert instance.valid?
|
186
|
-
instance.name =
|
185
|
+
instance.name = "foobar"
|
187
186
|
instance.slug = nil
|
188
187
|
instance.active = nil
|
189
188
|
refute instance.save
|
190
189
|
refute instance.valid?
|
191
|
-
assert_equal
|
190
|
+
assert_equal "foobar", instance.slug
|
192
191
|
end
|
193
192
|
end
|
194
193
|
|
195
194
|
test "should not update slug on save if slug validations fail" do
|
196
195
|
klass = Class.new model_class do
|
197
|
-
validates_length_of :slug, :
|
198
|
-
friendly_id :name, :
|
196
|
+
validates_length_of :slug, minimum: 2
|
197
|
+
friendly_id :name, use: :slugged
|
199
198
|
|
200
199
|
def self.name
|
201
200
|
"Journalist"
|
@@ -203,20 +202,19 @@ class SluggedTest < TestCaseClass
|
|
203
202
|
end
|
204
203
|
|
205
204
|
transaction do
|
206
|
-
instance = klass.new :
|
205
|
+
instance = klass.new name: "foo", active: true
|
207
206
|
assert instance.save
|
208
207
|
assert instance.valid?
|
209
|
-
instance.name =
|
208
|
+
instance.name = "x"
|
210
209
|
instance.slug = nil
|
211
210
|
instance.active = nil
|
212
211
|
refute instance.save
|
213
|
-
assert_equal
|
212
|
+
assert_equal "foo", instance.slug
|
214
213
|
end
|
215
214
|
end
|
216
215
|
end
|
217
216
|
|
218
217
|
class SlugGeneratorTest < TestCaseClass
|
219
|
-
|
220
218
|
include FriendlyId::Test
|
221
219
|
|
222
220
|
def model_class
|
@@ -232,11 +230,11 @@ class SlugGeneratorTest < TestCaseClass
|
|
232
230
|
# self.abstract_class = true
|
233
231
|
self.table_name = "journalists"
|
234
232
|
extend FriendlyId
|
235
|
-
friendly_id :name, :
|
233
|
+
friendly_id :name, use: :slugged, slug_column: "strange name"
|
236
234
|
end
|
237
235
|
|
238
236
|
begin
|
239
|
-
with_instance_of(model_class) {|record| assert model_class.friendly.find(record.friendly_id)}
|
237
|
+
with_instance_of(model_class) { |record| assert model_class.friendly.find(record.friendly_id) }
|
240
238
|
rescue ActiveRecord::StatementInvalid
|
241
239
|
flunk "column name was not quoted"
|
242
240
|
end
|
@@ -244,9 +242,9 @@ class SlugGeneratorTest < TestCaseClass
|
|
244
242
|
|
245
243
|
test "should not resequence lower sequences on update" do
|
246
244
|
transaction do
|
247
|
-
m1 = model_class.create! :
|
245
|
+
m1 = model_class.create! name: "a b c d"
|
248
246
|
assert_equal "a-b-c-d", m1.slug
|
249
|
-
model_class.create! :
|
247
|
+
model_class.create! name: "a b c d"
|
250
248
|
m1 = model_class.friendly.find(m1.id)
|
251
249
|
m1.save!
|
252
250
|
assert_equal "a-b-c-d", m1.slug
|
@@ -255,37 +253,35 @@ class SlugGeneratorTest < TestCaseClass
|
|
255
253
|
|
256
254
|
test "should correctly sequence slugs that end with numbers" do
|
257
255
|
transaction do
|
258
|
-
record1 = model_class.create! :
|
256
|
+
record1 = model_class.create! name: "Peugeot 206"
|
259
257
|
assert_equal "peugeot-206", record1.slug
|
260
|
-
record2 = model_class.create! :
|
261
|
-
assert_match(/\Apeugeot-206-([a-z0-9]
|
258
|
+
record2 = model_class.create! name: "Peugeot 206"
|
259
|
+
assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
|
262
260
|
end
|
263
261
|
end
|
264
262
|
|
265
263
|
test "should correctly sequence slugs with underscores" do
|
266
264
|
transaction do
|
267
|
-
Novelist.create! :
|
268
|
-
record2 = Novelist.create! :
|
269
|
-
assert_equal
|
265
|
+
Novelist.create! name: "wordsfail, buildings tumble"
|
266
|
+
record2 = Novelist.create! name: "word fail"
|
267
|
+
assert_equal "word_fail", record2.slug
|
270
268
|
end
|
271
269
|
end
|
272
270
|
|
273
271
|
test "should correctly sequence numeric slugs" do
|
274
272
|
transaction do
|
275
|
-
n2 = 2.times.map {Article.create :
|
273
|
+
n2 = 2.times.map { Article.create name: "123" }.last
|
276
274
|
assert_match(/\A123-.*/, n2.friendly_id)
|
277
275
|
end
|
278
276
|
end
|
279
|
-
|
280
277
|
end
|
281
278
|
|
282
279
|
class SlugSeparatorTest < TestCaseClass
|
283
|
-
|
284
280
|
include FriendlyId::Test
|
285
281
|
|
286
282
|
class Journalist < ActiveRecord::Base
|
287
283
|
extend FriendlyId
|
288
|
-
friendly_id :name, :
|
284
|
+
friendly_id :name, use: :slugged, sequence_separator: ":"
|
289
285
|
end
|
290
286
|
|
291
287
|
def model_class
|
@@ -294,7 +290,7 @@ class SlugSeparatorTest < TestCaseClass
|
|
294
290
|
|
295
291
|
test "should sequence with configured sequence separator" do
|
296
292
|
with_instance_of model_class do |record|
|
297
|
-
record2 = model_class.create! :
|
293
|
+
record2 = model_class.create! name: record.name
|
298
294
|
assert record2.friendly_id.match(/:.*\z/)
|
299
295
|
end
|
300
296
|
end
|
@@ -310,34 +306,32 @@ class SlugSeparatorTest < TestCaseClass
|
|
310
306
|
model_class = Class.new(ActiveRecord::Base) do
|
311
307
|
self.table_name = "journalists"
|
312
308
|
extend FriendlyId
|
313
|
-
friendly_id :name, :
|
309
|
+
friendly_id :name, use: :slugged, sequence_separator: "-"
|
314
310
|
def self.name
|
315
311
|
"Journalist"
|
316
312
|
end
|
317
313
|
end
|
318
314
|
transaction do
|
319
|
-
record1 = model_class.create! :
|
315
|
+
record1 = model_class.create! name: "Peugeot 206"
|
320
316
|
assert_equal "peugeot-206", record1.slug
|
321
|
-
record2 = model_class.create! :
|
322
|
-
assert_match(/\Apeugeot-206-([a-z0-9]
|
317
|
+
record2 = model_class.create! name: "Peugeot 206"
|
318
|
+
assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
|
323
319
|
end
|
324
320
|
end
|
325
321
|
|
326
322
|
test "should sequence blank slugs without a separator" do
|
327
|
-
with_instance_of model_class, :
|
328
|
-
assert_match(/\A([a-z0-9]
|
323
|
+
with_instance_of model_class, name: "" do |record|
|
324
|
+
assert_match(/\A([a-z0-9]+-){4}[a-z0-9]+\z/, record.slug)
|
329
325
|
end
|
330
326
|
end
|
331
|
-
|
332
327
|
end
|
333
328
|
|
334
329
|
class SlugLimitTest < TestCaseClass
|
335
|
-
|
336
330
|
include FriendlyId::Test
|
337
331
|
|
338
332
|
class Journalist < ActiveRecord::Base
|
339
333
|
extend FriendlyId
|
340
|
-
friendly_id :name, :
|
334
|
+
friendly_id :name, use: :slugged, slug_limit: 40
|
341
335
|
end
|
342
336
|
|
343
337
|
def model_class
|
@@ -346,48 +340,45 @@ class SlugLimitTest < TestCaseClass
|
|
346
340
|
|
347
341
|
test "should limit slug size" do
|
348
342
|
transaction do
|
349
|
-
m1 = model_class.create! :
|
350
|
-
assert_equal m1.slug,
|
351
|
-
m2 = model_class.create! :
|
343
|
+
m1 = model_class.create! name: "a" * 50
|
344
|
+
assert_equal m1.slug, "a" * 40
|
345
|
+
m2 = model_class.create! name: m1.name
|
352
346
|
m2.save!
|
353
347
|
# "aaa-<uid>"
|
354
|
-
assert_match(/\Aa{3}
|
348
|
+
assert_match(/\Aa{3}-/, m2.slug)
|
355
349
|
end
|
356
350
|
end
|
357
351
|
end
|
358
352
|
|
359
353
|
class DefaultScopeTest < TestCaseClass
|
360
|
-
|
361
354
|
include FriendlyId::Test
|
362
355
|
|
363
356
|
class Journalist < ActiveRecord::Base
|
364
357
|
extend FriendlyId
|
365
|
-
friendly_id :name, :
|
366
|
-
default_scope -> { where(:
|
358
|
+
friendly_id :name, use: :slugged
|
359
|
+
default_scope -> { where(active: true).order("id ASC") }
|
367
360
|
end
|
368
361
|
|
369
362
|
test "friendly_id should correctly sequence a default_scoped ordered table" do
|
370
363
|
transaction do
|
371
|
-
3.times { assert Journalist.create :
|
364
|
+
3.times { assert Journalist.create name: "a", active: true }
|
372
365
|
end
|
373
366
|
end
|
374
367
|
|
375
368
|
test "friendly_id should correctly sequence a default_scoped scoped table" do
|
376
369
|
transaction do
|
377
|
-
assert Journalist.create :
|
378
|
-
assert Journalist.create :
|
370
|
+
assert Journalist.create name: "a", active: false
|
371
|
+
assert Journalist.create name: "a", active: true
|
379
372
|
end
|
380
373
|
end
|
381
|
-
|
382
374
|
end
|
383
375
|
|
384
376
|
class UuidAsPrimaryKeyFindTest < TestCaseClass
|
385
|
-
|
386
377
|
include FriendlyId::Test
|
387
378
|
|
388
379
|
class MenuItem < ActiveRecord::Base
|
389
380
|
extend FriendlyId
|
390
|
-
friendly_id :name, :
|
381
|
+
friendly_id :name, use: :slugged
|
391
382
|
before_create :init_primary_key
|
392
383
|
|
393
384
|
def self.primary_key
|
@@ -400,6 +391,7 @@ class UuidAsPrimaryKeyFindTest < TestCaseClass
|
|
400
391
|
end
|
401
392
|
|
402
393
|
private
|
394
|
+
|
403
395
|
def init_primary_key
|
404
396
|
self.uuid_key = SecureRandom.uuid
|
405
397
|
end
|
@@ -427,46 +419,40 @@ class UuidAsPrimaryKeyFindTest < TestCaseClass
|
|
427
419
|
end
|
428
420
|
end
|
429
421
|
end
|
430
|
-
|
431
422
|
end
|
432
423
|
|
433
424
|
class UnderscoreAsSequenceSeparatorRegressionTest < TestCaseClass
|
434
|
-
|
435
425
|
include FriendlyId::Test
|
436
426
|
|
437
427
|
class Manual < ActiveRecord::Base
|
438
428
|
extend FriendlyId
|
439
|
-
friendly_id :name, :
|
429
|
+
friendly_id :name, use: :slugged, sequence_separator: "_"
|
440
430
|
end
|
441
431
|
|
442
432
|
test "should not create duplicate slugs" do
|
443
433
|
3.times do
|
444
434
|
transaction do
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
flunk "Tried to insert duplicate slug"
|
449
|
-
end
|
435
|
+
assert Manual.create! name: "foo"
|
436
|
+
rescue
|
437
|
+
flunk "Tried to insert duplicate slug"
|
450
438
|
end
|
451
439
|
end
|
452
440
|
end
|
453
|
-
|
454
441
|
end
|
455
442
|
|
456
443
|
# https://github.com/norman/friendly_id/issues/148
|
457
444
|
class FailedValidationAfterUpdateRegressionTest < TestCaseClass
|
458
|
-
|
459
445
|
include FriendlyId::Test
|
460
446
|
|
461
447
|
class Journalist < ActiveRecord::Base
|
462
448
|
extend FriendlyId
|
463
|
-
friendly_id :name, :
|
449
|
+
friendly_id :name, use: :slugged
|
464
450
|
validates_presence_of :slug_de
|
465
451
|
end
|
466
452
|
|
467
453
|
test "to_param should return the unchanged value if the slug changes before validation fails" do
|
468
454
|
transaction do
|
469
|
-
journalist = Journalist.create! :
|
455
|
+
journalist = Journalist.create! name: "Joseph Pulitzer", slug_de: "value"
|
470
456
|
assert_equal "joseph-pulitzer", journalist.to_param
|
471
457
|
assert journalist.valid?
|
472
458
|
assert journalist.persisted?
|
@@ -476,18 +462,45 @@ class FailedValidationAfterUpdateRegressionTest < TestCaseClass
|
|
476
462
|
assert_equal "joseph-pulitzer", journalist.to_param
|
477
463
|
end
|
478
464
|
end
|
465
|
+
end
|
466
|
+
|
467
|
+
# https://github.com/norman/friendly_id/issues/947
|
468
|
+
class GeneratingSlugWithValidationSkippedTest < TestCaseClass
|
469
|
+
include FriendlyId::Test
|
470
|
+
|
471
|
+
class Journalist < ActiveRecord::Base
|
472
|
+
extend FriendlyId
|
473
|
+
friendly_id :name, use: :slugged
|
474
|
+
end
|
475
|
+
|
476
|
+
test "should generate slug when skipping validation" do
|
477
|
+
transaction do
|
478
|
+
m1 = Journalist.new
|
479
|
+
m1.name = "Bob Timesletter"
|
480
|
+
m1.save(validate: false)
|
481
|
+
assert_equal "bob-timesletter", m1.slug
|
482
|
+
end
|
483
|
+
end
|
479
484
|
|
485
|
+
test "should generate slug when #valid? called" do
|
486
|
+
transaction do
|
487
|
+
m1 = Journalist.new
|
488
|
+
m1.name = "Bob Timesletter"
|
489
|
+
m1.valid?
|
490
|
+
m1.save(validate: false)
|
491
|
+
assert_equal "bob-timesletter", m1.slug
|
492
|
+
end
|
493
|
+
end
|
480
494
|
end
|
481
495
|
|
482
496
|
class ToParamTest < TestCaseClass
|
483
|
-
|
484
497
|
include FriendlyId::Test
|
485
498
|
|
486
499
|
class Journalist < ActiveRecord::Base
|
487
500
|
extend FriendlyId
|
488
501
|
validates_presence_of :active
|
489
|
-
validates_length_of :slug, :
|
490
|
-
friendly_id :name, :
|
502
|
+
validates_length_of :slug, minimum: 2
|
503
|
+
friendly_id :name, use: :slugged
|
491
504
|
|
492
505
|
attr_accessor :to_param_in_callback
|
493
506
|
|
@@ -501,86 +514,85 @@ class ToParamTest < TestCaseClass
|
|
501
514
|
end
|
502
515
|
|
503
516
|
test "to_param should return original slug if record failed validation" do
|
504
|
-
journalist = Journalist.new :
|
517
|
+
journalist = Journalist.new name: "Clark Kent", active: nil
|
505
518
|
refute journalist.save
|
506
|
-
assert_equal
|
519
|
+
assert_equal "clark-kent", journalist.to_param
|
507
520
|
end
|
508
521
|
|
509
522
|
test "to_param should clear slug attributes if slug attribute fails validation" do
|
510
|
-
journalist = Journalist.new :
|
523
|
+
journalist = Journalist.new name: "x", active: true
|
511
524
|
refute journalist.save
|
512
525
|
assert_nil journalist.to_param
|
513
526
|
end
|
514
527
|
|
515
528
|
test "to_param should clear slug attribute if slug attribute fails validation and unrelated validation fails" do
|
516
|
-
journalist = Journalist.new :
|
529
|
+
journalist = Journalist.new name: "x", active: nil
|
517
530
|
refute journalist.save
|
518
531
|
assert_nil journalist.to_param
|
519
532
|
end
|
520
533
|
|
521
534
|
test "to_param should use slugged attribute if record saved successfully" do
|
522
535
|
transaction do
|
523
|
-
journalist = Journalist.new :
|
536
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
524
537
|
assert journalist.save
|
525
|
-
assert_equal
|
538
|
+
assert_equal "clark-kent", journalist.to_param
|
526
539
|
end
|
527
540
|
end
|
528
541
|
|
529
542
|
test "to_param should use new slug if existing record changes but fails to save" do
|
530
543
|
transaction do
|
531
|
-
journalist = Journalist.new :
|
544
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
532
545
|
assert journalist.save
|
533
|
-
journalist.name =
|
546
|
+
journalist.name = "Superman"
|
534
547
|
journalist.slug = nil
|
535
548
|
journalist.active = nil
|
536
549
|
refute journalist.save
|
537
|
-
assert_equal
|
550
|
+
assert_equal "superman", journalist.to_param
|
538
551
|
end
|
539
552
|
end
|
540
553
|
|
541
554
|
test "to_param should use original slug if new slug attribute is not valid" do
|
542
555
|
transaction do
|
543
|
-
journalist = Journalist.new :
|
556
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
544
557
|
assert journalist.save
|
545
|
-
journalist.name =
|
558
|
+
journalist.name = "x"
|
546
559
|
journalist.slug = nil
|
547
560
|
journalist.active = nil
|
548
561
|
refute journalist.save
|
549
|
-
assert_equal
|
562
|
+
assert_equal "clark-kent", journalist.to_param
|
550
563
|
end
|
551
564
|
end
|
552
565
|
|
553
566
|
test "to_param should use new slug if existing record changes successfully" do
|
554
567
|
transaction do
|
555
|
-
journalist = Journalist.new :
|
568
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
556
569
|
assert journalist.save
|
557
|
-
journalist.name =
|
570
|
+
journalist.name = "Superman"
|
558
571
|
journalist.slug = nil
|
559
572
|
assert journalist.save
|
560
|
-
assert_equal
|
573
|
+
assert_equal "superman", journalist.to_param
|
561
574
|
end
|
562
575
|
end
|
563
576
|
|
564
577
|
test "to_param should use new slug within callbacks if new record is saved successfully" do
|
565
578
|
transaction do
|
566
|
-
journalist = Journalist.new :
|
579
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
567
580
|
assert journalist.save
|
568
|
-
assert_equal
|
581
|
+
assert_equal "clark-kent", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
569
582
|
end
|
570
583
|
end
|
571
584
|
|
572
585
|
test "to_param should use new slug within callbacks if existing record changes successfully" do
|
573
586
|
transaction do
|
574
|
-
journalist = Journalist.new :
|
587
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
575
588
|
assert journalist.save
|
576
589
|
assert journalist.valid?
|
577
|
-
journalist.name =
|
590
|
+
journalist.name = "Superman"
|
578
591
|
journalist.slug = nil
|
579
592
|
assert journalist.save, "save should be successful"
|
580
|
-
assert_equal
|
593
|
+
assert_equal "superman", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
581
594
|
end
|
582
595
|
end
|
583
|
-
|
584
596
|
end
|
585
597
|
|
586
598
|
class ConfigurableRoutesTest < TestCaseClass
|
@@ -589,18 +601,18 @@ class ConfigurableRoutesTest < TestCaseClass
|
|
589
601
|
class Article < ActiveRecord::Base
|
590
602
|
extend FriendlyId
|
591
603
|
|
592
|
-
friendly_id :name, :
|
604
|
+
friendly_id :name, use: :slugged, routes: :friendly
|
593
605
|
end
|
594
606
|
|
595
607
|
class Novel < ActiveRecord::Base
|
596
608
|
extend FriendlyId
|
597
609
|
|
598
|
-
friendly_id :name, :
|
610
|
+
friendly_id :name, use: :slugged, routes: :default
|
599
611
|
end
|
600
612
|
|
601
613
|
test "to_param should return a friendly id when the routes option is set to :friendly" do
|
602
614
|
transaction do
|
603
|
-
article = Article.create! :
|
615
|
+
article = Article.create! name: "Titanic Hits; Iceberg Sinks"
|
604
616
|
|
605
617
|
assert_equal "titanic-hits-iceberg-sinks", article.to_param
|
606
618
|
end
|
@@ -608,7 +620,7 @@ class ConfigurableRoutesTest < TestCaseClass
|
|
608
620
|
|
609
621
|
test "to_param should return the id when the routes option is set to anything but friendly" do
|
610
622
|
transaction do
|
611
|
-
novel = Novel.create! :
|
623
|
+
novel = Novel.create! name: "Don Quixote"
|
612
624
|
|
613
625
|
assert_equal novel.id.to_s, novel.to_param
|
614
626
|
end
|