friendly_id 5.4.2 → 5.5.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
- checksums.yaml.gz.sig +0 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/test.yml +34 -25
- data/Changelog.md +6 -0
- data/Gemfile +9 -13
- data/README.md +21 -0
- 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 +5 -5
- data/lib/friendly_id/base.rb +57 -60
- data/lib/friendly_id/candidates.rb +9 -11
- data/lib/friendly_id/configuration.rb +6 -7
- data/lib/friendly_id/finder_methods.rb +26 -11
- data/lib/friendly_id/finders.rb +63 -66
- data/lib/friendly_id/history.rb +59 -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 +28 -32
- data/lib/friendly_id/scoped.rb +97 -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 +75 -69
- data/lib/friendly_id/slug.rb +1 -2
- data/lib/friendly_id/slug_generator.rb +1 -3
- data/lib/friendly_id/slugged.rb +234 -238
- data/lib/friendly_id/version.rb +1 -1
- data/lib/friendly_id.rb +41 -45
- 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 +52 -5
- data/test/generator_test.rb +16 -26
- data/test/helper.rb +29 -22
- 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 +102 -121
- data/test/sti_test.rb +19 -21
- data.tar.gz.sig +0 -0
- metadata +35 -30
- metadata.gz.sig +1 -1
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,49 +462,45 @@ class FailedValidationAfterUpdateRegressionTest < TestCaseClass
|
|
476
462
|
assert_equal "joseph-pulitzer", journalist.to_param
|
477
463
|
end
|
478
464
|
end
|
479
|
-
|
480
465
|
end
|
481
466
|
|
482
467
|
# https://github.com/norman/friendly_id/issues/947
|
483
468
|
class GeneratingSlugWithValidationSkippedTest < TestCaseClass
|
484
|
-
|
485
469
|
include FriendlyId::Test
|
486
470
|
|
487
471
|
class Journalist < ActiveRecord::Base
|
488
472
|
extend FriendlyId
|
489
|
-
friendly_id :name, :
|
473
|
+
friendly_id :name, use: :slugged
|
490
474
|
end
|
491
475
|
|
492
476
|
test "should generate slug when skipping validation" do
|
493
477
|
transaction do
|
494
478
|
m1 = Journalist.new
|
495
|
-
m1.name =
|
479
|
+
m1.name = "Bob Timesletter"
|
496
480
|
m1.save(validate: false)
|
497
|
-
assert_equal
|
481
|
+
assert_equal "bob-timesletter", m1.slug
|
498
482
|
end
|
499
483
|
end
|
500
484
|
|
501
485
|
test "should generate slug when #valid? called" do
|
502
486
|
transaction do
|
503
487
|
m1 = Journalist.new
|
504
|
-
m1.name =
|
488
|
+
m1.name = "Bob Timesletter"
|
505
489
|
m1.valid?
|
506
490
|
m1.save(validate: false)
|
507
|
-
assert_equal
|
491
|
+
assert_equal "bob-timesletter", m1.slug
|
508
492
|
end
|
509
493
|
end
|
510
|
-
|
511
494
|
end
|
512
495
|
|
513
496
|
class ToParamTest < TestCaseClass
|
514
|
-
|
515
497
|
include FriendlyId::Test
|
516
498
|
|
517
499
|
class Journalist < ActiveRecord::Base
|
518
500
|
extend FriendlyId
|
519
501
|
validates_presence_of :active
|
520
|
-
validates_length_of :slug, :
|
521
|
-
friendly_id :name, :
|
502
|
+
validates_length_of :slug, minimum: 2
|
503
|
+
friendly_id :name, use: :slugged
|
522
504
|
|
523
505
|
attr_accessor :to_param_in_callback
|
524
506
|
|
@@ -532,86 +514,85 @@ class ToParamTest < TestCaseClass
|
|
532
514
|
end
|
533
515
|
|
534
516
|
test "to_param should return original slug if record failed validation" do
|
535
|
-
journalist = Journalist.new :
|
517
|
+
journalist = Journalist.new name: "Clark Kent", active: nil
|
536
518
|
refute journalist.save
|
537
|
-
assert_equal
|
519
|
+
assert_equal "clark-kent", journalist.to_param
|
538
520
|
end
|
539
521
|
|
540
522
|
test "to_param should clear slug attributes if slug attribute fails validation" do
|
541
|
-
journalist = Journalist.new :
|
523
|
+
journalist = Journalist.new name: "x", active: true
|
542
524
|
refute journalist.save
|
543
525
|
assert_nil journalist.to_param
|
544
526
|
end
|
545
527
|
|
546
528
|
test "to_param should clear slug attribute if slug attribute fails validation and unrelated validation fails" do
|
547
|
-
journalist = Journalist.new :
|
529
|
+
journalist = Journalist.new name: "x", active: nil
|
548
530
|
refute journalist.save
|
549
531
|
assert_nil journalist.to_param
|
550
532
|
end
|
551
533
|
|
552
534
|
test "to_param should use slugged attribute if record saved successfully" do
|
553
535
|
transaction do
|
554
|
-
journalist = Journalist.new :
|
536
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
555
537
|
assert journalist.save
|
556
|
-
assert_equal
|
538
|
+
assert_equal "clark-kent", journalist.to_param
|
557
539
|
end
|
558
540
|
end
|
559
541
|
|
560
542
|
test "to_param should use new slug if existing record changes but fails to save" do
|
561
543
|
transaction do
|
562
|
-
journalist = Journalist.new :
|
544
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
563
545
|
assert journalist.save
|
564
|
-
journalist.name =
|
546
|
+
journalist.name = "Superman"
|
565
547
|
journalist.slug = nil
|
566
548
|
journalist.active = nil
|
567
549
|
refute journalist.save
|
568
|
-
assert_equal
|
550
|
+
assert_equal "superman", journalist.to_param
|
569
551
|
end
|
570
552
|
end
|
571
553
|
|
572
554
|
test "to_param should use original slug if new slug attribute is not valid" do
|
573
555
|
transaction do
|
574
|
-
journalist = Journalist.new :
|
556
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
575
557
|
assert journalist.save
|
576
|
-
journalist.name =
|
558
|
+
journalist.name = "x"
|
577
559
|
journalist.slug = nil
|
578
560
|
journalist.active = nil
|
579
561
|
refute journalist.save
|
580
|
-
assert_equal
|
562
|
+
assert_equal "clark-kent", journalist.to_param
|
581
563
|
end
|
582
564
|
end
|
583
565
|
|
584
566
|
test "to_param should use new slug if existing record changes successfully" do
|
585
567
|
transaction do
|
586
|
-
journalist = Journalist.new :
|
568
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
587
569
|
assert journalist.save
|
588
|
-
journalist.name =
|
570
|
+
journalist.name = "Superman"
|
589
571
|
journalist.slug = nil
|
590
572
|
assert journalist.save
|
591
|
-
assert_equal
|
573
|
+
assert_equal "superman", journalist.to_param
|
592
574
|
end
|
593
575
|
end
|
594
576
|
|
595
577
|
test "to_param should use new slug within callbacks if new record is saved successfully" do
|
596
578
|
transaction do
|
597
|
-
journalist = Journalist.new :
|
579
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
598
580
|
assert journalist.save
|
599
|
-
assert_equal
|
581
|
+
assert_equal "clark-kent", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
600
582
|
end
|
601
583
|
end
|
602
584
|
|
603
585
|
test "to_param should use new slug within callbacks if existing record changes successfully" do
|
604
586
|
transaction do
|
605
|
-
journalist = Journalist.new :
|
587
|
+
journalist = Journalist.new name: "Clark Kent", active: true
|
606
588
|
assert journalist.save
|
607
589
|
assert journalist.valid?
|
608
|
-
journalist.name =
|
590
|
+
journalist.name = "Superman"
|
609
591
|
journalist.slug = nil
|
610
592
|
assert journalist.save, "save should be successful"
|
611
|
-
assert_equal
|
593
|
+
assert_equal "superman", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
612
594
|
end
|
613
595
|
end
|
614
|
-
|
615
596
|
end
|
616
597
|
|
617
598
|
class ConfigurableRoutesTest < TestCaseClass
|
@@ -620,18 +601,18 @@ class ConfigurableRoutesTest < TestCaseClass
|
|
620
601
|
class Article < ActiveRecord::Base
|
621
602
|
extend FriendlyId
|
622
603
|
|
623
|
-
friendly_id :name, :
|
604
|
+
friendly_id :name, use: :slugged, routes: :friendly
|
624
605
|
end
|
625
606
|
|
626
607
|
class Novel < ActiveRecord::Base
|
627
608
|
extend FriendlyId
|
628
609
|
|
629
|
-
friendly_id :name, :
|
610
|
+
friendly_id :name, use: :slugged, routes: :default
|
630
611
|
end
|
631
612
|
|
632
613
|
test "to_param should return a friendly id when the routes option is set to :friendly" do
|
633
614
|
transaction do
|
634
|
-
article = Article.create! :
|
615
|
+
article = Article.create! name: "Titanic Hits; Iceberg Sinks"
|
635
616
|
|
636
617
|
assert_equal "titanic-hits-iceberg-sinks", article.to_param
|
637
618
|
end
|
@@ -639,7 +620,7 @@ class ConfigurableRoutesTest < TestCaseClass
|
|
639
620
|
|
640
621
|
test "to_param should return the id when the routes option is set to anything but friendly" do
|
641
622
|
transaction do
|
642
|
-
novel = Novel.create! :
|
623
|
+
novel = Novel.create! name: "Don Quixote"
|
643
624
|
|
644
625
|
assert_equal novel.id.to_s, novel.to_param
|
645
626
|
end
|