friendly_id 5.6.0 → 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/lib/friendly_id/version.rb +1 -1
- metadata +2 -44
- 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/release.yml +0 -29
- data/.github/workflows/test.yml +0 -86
- data/.gitignore +0 -14
- data/.yardopts +0 -8
- data/CONTRIBUTING.md +0 -11
- data/Gemfile +0 -23
- data/Rakefile +0 -100
- data/UPGRADING.md +0 -115
- data/bench.rb +0 -84
- data/friendly_id.gemspec +0 -31
- 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/gemfiles/Gemfile.rails-7.1.rb +0 -22
- data/gemfiles/Gemfile.rails-7.2.rb +0 -22
- data/gemfiles/Gemfile.rails-8.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 -100
- 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/test/slugged_test.rb
DELETED
|
@@ -1,628 +0,0 @@
|
|
|
1
|
-
require "helper"
|
|
2
|
-
|
|
3
|
-
class Journalist < ActiveRecord::Base
|
|
4
|
-
extend FriendlyId
|
|
5
|
-
friendly_id :name, use: :slugged
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
class Article < ActiveRecord::Base
|
|
9
|
-
extend FriendlyId
|
|
10
|
-
friendly_id :name, use: :slugged
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
class Novelist < ActiveRecord::Base
|
|
14
|
-
extend FriendlyId
|
|
15
|
-
friendly_id :name, use: :slugged, sequence_separator: "_"
|
|
16
|
-
|
|
17
|
-
def normalize_friendly_id(string)
|
|
18
|
-
super.tr("-", "_")
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
class SluggedTest < TestCaseClass
|
|
23
|
-
include FriendlyId::Test
|
|
24
|
-
include FriendlyId::Test::Shared::Core
|
|
25
|
-
include FriendlyId::Test::Shared::Slugged
|
|
26
|
-
|
|
27
|
-
def model_class
|
|
28
|
-
Journalist
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
test "should allow validations on the slug" do
|
|
32
|
-
model_class = Class.new(ActiveRecord::Base) do
|
|
33
|
-
self.table_name = "articles"
|
|
34
|
-
extend FriendlyId
|
|
35
|
-
friendly_id :name, use: :slugged
|
|
36
|
-
validates_length_of :slug, maximum: 1
|
|
37
|
-
def self.name
|
|
38
|
-
"Article"
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
instance = model_class.new name: "hello"
|
|
42
|
-
refute instance.valid?
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
test "should allow nil slugs" do
|
|
46
|
-
transaction do
|
|
47
|
-
m1 = model_class.create!
|
|
48
|
-
model_class.create!
|
|
49
|
-
assert_nil m1.slug
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
test "should not break validates_uniqueness_of" do
|
|
54
|
-
model_class = Class.new(ActiveRecord::Base) do
|
|
55
|
-
self.table_name = "journalists"
|
|
56
|
-
extend FriendlyId
|
|
57
|
-
friendly_id :name, use: :slugged
|
|
58
|
-
validates_uniqueness_of :slug_en
|
|
59
|
-
def self.name
|
|
60
|
-
"Journalist"
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
transaction do
|
|
64
|
-
instance = model_class.create! name: "hello", slug_en: "hello"
|
|
65
|
-
instance2 = model_class.create name: "hello", slug_en: "hello"
|
|
66
|
-
assert instance.valid?
|
|
67
|
-
refute instance2.valid?
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
test "should allow a record to reuse its own slug" do
|
|
72
|
-
with_instance_of(model_class) do |record|
|
|
73
|
-
old_id = record.friendly_id
|
|
74
|
-
record.slug = nil
|
|
75
|
-
record.save!
|
|
76
|
-
assert_equal old_id, record.friendly_id
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
test "should not update matching slug" do
|
|
81
|
-
klass = Class.new model_class do
|
|
82
|
-
def should_generate_new_friendly_id?
|
|
83
|
-
name_changed?
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
with_instance_of klass do |record|
|
|
87
|
-
old_id = record.friendly_id
|
|
88
|
-
record.name += " "
|
|
89
|
-
record.save!
|
|
90
|
-
assert_equal old_id, record.friendly_id
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
test "should set slug on create if unrelated validations fail" do
|
|
95
|
-
klass = Class.new model_class do
|
|
96
|
-
validates_presence_of :active
|
|
97
|
-
friendly_id :name, use: :slugged
|
|
98
|
-
|
|
99
|
-
def self.name
|
|
100
|
-
"Journalist"
|
|
101
|
-
end
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
transaction do
|
|
105
|
-
instance = klass.new name: "foo"
|
|
106
|
-
refute instance.save
|
|
107
|
-
refute instance.valid?
|
|
108
|
-
assert_equal "foo", instance.slug
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
test "should not set slug on create if slug validation fails" do
|
|
113
|
-
klass = Class.new model_class do
|
|
114
|
-
validates_presence_of :active
|
|
115
|
-
validates_length_of :slug, minimum: 2
|
|
116
|
-
friendly_id :name, use: :slugged
|
|
117
|
-
|
|
118
|
-
def self.name
|
|
119
|
-
"Journalist"
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
transaction do
|
|
124
|
-
instance = klass.new name: "x"
|
|
125
|
-
refute instance.save
|
|
126
|
-
refute instance.valid?
|
|
127
|
-
assert_nil instance.slug
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
test "should set slug on create if unrelated validations fail with custom slug_column" do
|
|
132
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
133
|
-
self.table_name = "authors"
|
|
134
|
-
extend FriendlyId
|
|
135
|
-
validates_presence_of :active
|
|
136
|
-
friendly_id :name, use: :slugged, slug_column: :subdomain
|
|
137
|
-
|
|
138
|
-
def self.name
|
|
139
|
-
"Author"
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
transaction do
|
|
144
|
-
instance = klass.new name: "foo"
|
|
145
|
-
refute instance.save
|
|
146
|
-
refute instance.valid?
|
|
147
|
-
assert_equal "foo", instance.subdomain
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
test "should not set slug on create if custom slug column validations fail" do
|
|
152
|
-
klass = Class.new(ActiveRecord::Base) do
|
|
153
|
-
self.table_name = "authors"
|
|
154
|
-
extend FriendlyId
|
|
155
|
-
validates_length_of :subdomain, minimum: 2
|
|
156
|
-
friendly_id :name, use: :slugged, slug_column: :subdomain
|
|
157
|
-
|
|
158
|
-
def self.name
|
|
159
|
-
"Author"
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
transaction do
|
|
164
|
-
instance = klass.new name: "x"
|
|
165
|
-
refute instance.save
|
|
166
|
-
refute instance.valid?
|
|
167
|
-
assert_nil instance.subdomain
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
test "should keep new slug on save if unrelated validations fail" do
|
|
172
|
-
klass = Class.new model_class do
|
|
173
|
-
validates_presence_of :active
|
|
174
|
-
friendly_id :name, use: :slugged
|
|
175
|
-
|
|
176
|
-
def self.name
|
|
177
|
-
"Journalist"
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
transaction do
|
|
182
|
-
instance = klass.new name: "foo", active: true
|
|
183
|
-
assert instance.save
|
|
184
|
-
assert instance.valid?
|
|
185
|
-
instance.name = "foobar"
|
|
186
|
-
instance.slug = nil
|
|
187
|
-
instance.active = nil
|
|
188
|
-
refute instance.save
|
|
189
|
-
refute instance.valid?
|
|
190
|
-
assert_equal "foobar", instance.slug
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
test "should not update slug on save if slug validations fail" do
|
|
195
|
-
klass = Class.new model_class do
|
|
196
|
-
validates_length_of :slug, minimum: 2
|
|
197
|
-
friendly_id :name, use: :slugged
|
|
198
|
-
|
|
199
|
-
def self.name
|
|
200
|
-
"Journalist"
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
transaction do
|
|
205
|
-
instance = klass.new name: "foo", active: true
|
|
206
|
-
assert instance.save
|
|
207
|
-
assert instance.valid?
|
|
208
|
-
instance.name = "x"
|
|
209
|
-
instance.slug = nil
|
|
210
|
-
instance.active = nil
|
|
211
|
-
refute instance.save
|
|
212
|
-
assert_equal "foo", instance.slug
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
class SlugGeneratorTest < TestCaseClass
|
|
218
|
-
include FriendlyId::Test
|
|
219
|
-
|
|
220
|
-
def model_class
|
|
221
|
-
Journalist
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
test "should quote column names" do
|
|
225
|
-
model_class = Class.new(ActiveRecord::Base) do
|
|
226
|
-
# This has been added in 635731bb to fix MySQL/Rubinius. It may still
|
|
227
|
-
# be necessary, but causes an exception to be raised on Rails 4, so I'm
|
|
228
|
-
# commenting it out. If it causes MySQL/Rubinius to fail again we'll
|
|
229
|
-
# look for another solution.
|
|
230
|
-
# self.abstract_class = true
|
|
231
|
-
self.table_name = "journalists"
|
|
232
|
-
extend FriendlyId
|
|
233
|
-
friendly_id :name, use: :slugged, slug_column: "strange name"
|
|
234
|
-
end
|
|
235
|
-
|
|
236
|
-
begin
|
|
237
|
-
with_instance_of(model_class) { |record| assert model_class.friendly.find(record.friendly_id) }
|
|
238
|
-
rescue ActiveRecord::StatementInvalid
|
|
239
|
-
flunk "column name was not quoted"
|
|
240
|
-
end
|
|
241
|
-
end
|
|
242
|
-
|
|
243
|
-
test "should not resequence lower sequences on update" do
|
|
244
|
-
transaction do
|
|
245
|
-
m1 = model_class.create! name: "a b c d"
|
|
246
|
-
assert_equal "a-b-c-d", m1.slug
|
|
247
|
-
model_class.create! name: "a b c d"
|
|
248
|
-
m1 = model_class.friendly.find(m1.id)
|
|
249
|
-
m1.save!
|
|
250
|
-
assert_equal "a-b-c-d", m1.slug
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
test "should correctly sequence slugs that end with numbers" do
|
|
255
|
-
transaction do
|
|
256
|
-
record1 = model_class.create! name: "Peugeot 206"
|
|
257
|
-
assert_equal "peugeot-206", record1.slug
|
|
258
|
-
record2 = model_class.create! name: "Peugeot 206"
|
|
259
|
-
assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
test "should correctly sequence slugs with underscores" do
|
|
264
|
-
transaction do
|
|
265
|
-
Novelist.create! name: "wordsfail, buildings tumble"
|
|
266
|
-
record2 = Novelist.create! name: "word fail"
|
|
267
|
-
assert_equal "word_fail", record2.slug
|
|
268
|
-
end
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
test "should correctly sequence numeric slugs" do
|
|
272
|
-
transaction do
|
|
273
|
-
n2 = 2.times.map { Article.create name: "123" }.last
|
|
274
|
-
assert_match(/\A123-.*/, n2.friendly_id)
|
|
275
|
-
end
|
|
276
|
-
end
|
|
277
|
-
end
|
|
278
|
-
|
|
279
|
-
class SlugSeparatorTest < TestCaseClass
|
|
280
|
-
include FriendlyId::Test
|
|
281
|
-
|
|
282
|
-
class Journalist < ActiveRecord::Base
|
|
283
|
-
extend FriendlyId
|
|
284
|
-
friendly_id :name, use: :slugged, sequence_separator: ":"
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def model_class
|
|
288
|
-
Journalist
|
|
289
|
-
end
|
|
290
|
-
|
|
291
|
-
test "should sequence with configured sequence separator" do
|
|
292
|
-
with_instance_of model_class do |record|
|
|
293
|
-
record2 = model_class.create! name: record.name
|
|
294
|
-
assert record2.friendly_id.match(/:.*\z/)
|
|
295
|
-
end
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
test "should detect when a stored slug has been cleared" do
|
|
299
|
-
with_instance_of model_class do |record|
|
|
300
|
-
record.slug = nil
|
|
301
|
-
assert record.should_generate_new_friendly_id?
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
|
|
305
|
-
test "should correctly sequence slugs that uses single dashes as sequence separator" do
|
|
306
|
-
model_class = Class.new(ActiveRecord::Base) do
|
|
307
|
-
self.table_name = "journalists"
|
|
308
|
-
extend FriendlyId
|
|
309
|
-
friendly_id :name, use: :slugged, sequence_separator: "-"
|
|
310
|
-
def self.name
|
|
311
|
-
"Journalist"
|
|
312
|
-
end
|
|
313
|
-
end
|
|
314
|
-
transaction do
|
|
315
|
-
record1 = model_class.create! name: "Peugeot 206"
|
|
316
|
-
assert_equal "peugeot-206", record1.slug
|
|
317
|
-
record2 = model_class.create! name: "Peugeot 206"
|
|
318
|
-
assert_match(/\Apeugeot-206-([a-z0-9]+-){4}[a-z0-9]+\z/, record2.slug)
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
test "should sequence blank slugs without a separator" do
|
|
323
|
-
with_instance_of model_class, name: "" do |record|
|
|
324
|
-
assert_match(/\A([a-z0-9]+-){4}[a-z0-9]+\z/, record.slug)
|
|
325
|
-
end
|
|
326
|
-
end
|
|
327
|
-
end
|
|
328
|
-
|
|
329
|
-
class SlugLimitTest < TestCaseClass
|
|
330
|
-
include FriendlyId::Test
|
|
331
|
-
|
|
332
|
-
class Journalist < ActiveRecord::Base
|
|
333
|
-
extend FriendlyId
|
|
334
|
-
friendly_id :name, use: :slugged, slug_limit: 40
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
def model_class
|
|
338
|
-
Journalist
|
|
339
|
-
end
|
|
340
|
-
|
|
341
|
-
test "should limit slug size" do
|
|
342
|
-
transaction do
|
|
343
|
-
m1 = model_class.create! name: "a" * 50
|
|
344
|
-
assert_equal m1.slug, "a" * 40
|
|
345
|
-
m2 = model_class.create! name: m1.name
|
|
346
|
-
m2.save!
|
|
347
|
-
# "aaa-<uid>"
|
|
348
|
-
assert_match(/\Aa{3}-/, m2.slug)
|
|
349
|
-
end
|
|
350
|
-
end
|
|
351
|
-
end
|
|
352
|
-
|
|
353
|
-
class DefaultScopeTest < TestCaseClass
|
|
354
|
-
include FriendlyId::Test
|
|
355
|
-
|
|
356
|
-
class Journalist < ActiveRecord::Base
|
|
357
|
-
extend FriendlyId
|
|
358
|
-
friendly_id :name, use: :slugged
|
|
359
|
-
default_scope -> { where(active: true).order("id ASC") }
|
|
360
|
-
end
|
|
361
|
-
|
|
362
|
-
test "friendly_id should correctly sequence a default_scoped ordered table" do
|
|
363
|
-
transaction do
|
|
364
|
-
3.times { assert Journalist.create name: "a", active: true }
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
test "friendly_id should correctly sequence a default_scoped scoped table" do
|
|
369
|
-
transaction do
|
|
370
|
-
assert Journalist.create name: "a", active: false
|
|
371
|
-
assert Journalist.create name: "a", active: true
|
|
372
|
-
end
|
|
373
|
-
end
|
|
374
|
-
end
|
|
375
|
-
|
|
376
|
-
class UuidAsPrimaryKeyFindTest < TestCaseClass
|
|
377
|
-
include FriendlyId::Test
|
|
378
|
-
|
|
379
|
-
class MenuItem < ActiveRecord::Base
|
|
380
|
-
extend FriendlyId
|
|
381
|
-
friendly_id :name, use: :slugged
|
|
382
|
-
before_create :init_primary_key
|
|
383
|
-
|
|
384
|
-
def self.primary_key
|
|
385
|
-
"uuid_key"
|
|
386
|
-
end
|
|
387
|
-
|
|
388
|
-
# Overwrite the method added by FriendlyId
|
|
389
|
-
def self.primary_key_type
|
|
390
|
-
:uuid
|
|
391
|
-
end
|
|
392
|
-
|
|
393
|
-
private
|
|
394
|
-
|
|
395
|
-
def init_primary_key
|
|
396
|
-
self.uuid_key = SecureRandom.uuid
|
|
397
|
-
end
|
|
398
|
-
end
|
|
399
|
-
|
|
400
|
-
def model_class
|
|
401
|
-
MenuItem
|
|
402
|
-
end
|
|
403
|
-
|
|
404
|
-
test "should have a uuid_key as a primary key" do
|
|
405
|
-
assert_equal "uuid_key", model_class.primary_key
|
|
406
|
-
assert_equal :uuid, model_class.primary_key_type
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
test "should be findable by the UUID primary key" do
|
|
410
|
-
with_instance_of(model_class) do |record|
|
|
411
|
-
assert model_class.friendly.find record.id
|
|
412
|
-
end
|
|
413
|
-
end
|
|
414
|
-
|
|
415
|
-
test "should handle a string that simply contains a UUID correctly" do
|
|
416
|
-
with_instance_of(model_class) do |record|
|
|
417
|
-
assert_raises(ActiveRecord::RecordNotFound) do
|
|
418
|
-
model_class.friendly.find "test-#{SecureRandom.uuid}"
|
|
419
|
-
end
|
|
420
|
-
end
|
|
421
|
-
end
|
|
422
|
-
end
|
|
423
|
-
|
|
424
|
-
class UnderscoreAsSequenceSeparatorRegressionTest < TestCaseClass
|
|
425
|
-
include FriendlyId::Test
|
|
426
|
-
|
|
427
|
-
class Manual < ActiveRecord::Base
|
|
428
|
-
extend FriendlyId
|
|
429
|
-
friendly_id :name, use: :slugged, sequence_separator: "_"
|
|
430
|
-
end
|
|
431
|
-
|
|
432
|
-
test "should not create duplicate slugs" do
|
|
433
|
-
3.times do
|
|
434
|
-
transaction do
|
|
435
|
-
assert Manual.create! name: "foo"
|
|
436
|
-
rescue
|
|
437
|
-
flunk "Tried to insert duplicate slug"
|
|
438
|
-
end
|
|
439
|
-
end
|
|
440
|
-
end
|
|
441
|
-
end
|
|
442
|
-
|
|
443
|
-
# https://github.com/norman/friendly_id/issues/148
|
|
444
|
-
class FailedValidationAfterUpdateRegressionTest < TestCaseClass
|
|
445
|
-
include FriendlyId::Test
|
|
446
|
-
|
|
447
|
-
class Journalist < ActiveRecord::Base
|
|
448
|
-
extend FriendlyId
|
|
449
|
-
friendly_id :name, use: :slugged
|
|
450
|
-
validates_presence_of :slug_de
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
test "to_param should return the unchanged value if the slug changes before validation fails" do
|
|
454
|
-
transaction do
|
|
455
|
-
journalist = Journalist.create! name: "Joseph Pulitzer", slug_de: "value"
|
|
456
|
-
assert_equal "joseph-pulitzer", journalist.to_param
|
|
457
|
-
assert journalist.valid?
|
|
458
|
-
assert journalist.persisted?
|
|
459
|
-
journalist.name = "Joe Pulitzer"
|
|
460
|
-
journalist.slug_de = nil
|
|
461
|
-
assert !journalist.valid?
|
|
462
|
-
assert_equal "joseph-pulitzer", journalist.to_param
|
|
463
|
-
end
|
|
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
|
|
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
|
|
494
|
-
end
|
|
495
|
-
|
|
496
|
-
class ToParamTest < TestCaseClass
|
|
497
|
-
include FriendlyId::Test
|
|
498
|
-
|
|
499
|
-
class Journalist < ActiveRecord::Base
|
|
500
|
-
extend FriendlyId
|
|
501
|
-
validates_presence_of :active
|
|
502
|
-
validates_length_of :slug, minimum: 2
|
|
503
|
-
friendly_id :name, use: :slugged
|
|
504
|
-
|
|
505
|
-
attr_accessor :to_param_in_callback
|
|
506
|
-
|
|
507
|
-
after_save do
|
|
508
|
-
self.to_param_in_callback = to_param
|
|
509
|
-
end
|
|
510
|
-
end
|
|
511
|
-
|
|
512
|
-
test "to_param should return nil if record is unpersisted" do
|
|
513
|
-
assert_nil Journalist.new.to_param
|
|
514
|
-
end
|
|
515
|
-
|
|
516
|
-
test "to_param should return original slug if record failed validation" do
|
|
517
|
-
journalist = Journalist.new name: "Clark Kent", active: nil
|
|
518
|
-
refute journalist.save
|
|
519
|
-
assert_equal "clark-kent", journalist.to_param
|
|
520
|
-
end
|
|
521
|
-
|
|
522
|
-
test "to_param should clear slug attributes if slug attribute fails validation" do
|
|
523
|
-
journalist = Journalist.new name: "x", active: true
|
|
524
|
-
refute journalist.save
|
|
525
|
-
assert_nil journalist.to_param
|
|
526
|
-
end
|
|
527
|
-
|
|
528
|
-
test "to_param should clear slug attribute if slug attribute fails validation and unrelated validation fails" do
|
|
529
|
-
journalist = Journalist.new name: "x", active: nil
|
|
530
|
-
refute journalist.save
|
|
531
|
-
assert_nil journalist.to_param
|
|
532
|
-
end
|
|
533
|
-
|
|
534
|
-
test "to_param should use slugged attribute if record saved successfully" do
|
|
535
|
-
transaction do
|
|
536
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
537
|
-
assert journalist.save
|
|
538
|
-
assert_equal "clark-kent", journalist.to_param
|
|
539
|
-
end
|
|
540
|
-
end
|
|
541
|
-
|
|
542
|
-
test "to_param should use new slug if existing record changes but fails to save" do
|
|
543
|
-
transaction do
|
|
544
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
545
|
-
assert journalist.save
|
|
546
|
-
journalist.name = "Superman"
|
|
547
|
-
journalist.slug = nil
|
|
548
|
-
journalist.active = nil
|
|
549
|
-
refute journalist.save
|
|
550
|
-
assert_equal "superman", journalist.to_param
|
|
551
|
-
end
|
|
552
|
-
end
|
|
553
|
-
|
|
554
|
-
test "to_param should use original slug if new slug attribute is not valid" do
|
|
555
|
-
transaction do
|
|
556
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
557
|
-
assert journalist.save
|
|
558
|
-
journalist.name = "x"
|
|
559
|
-
journalist.slug = nil
|
|
560
|
-
journalist.active = nil
|
|
561
|
-
refute journalist.save
|
|
562
|
-
assert_equal "clark-kent", journalist.to_param
|
|
563
|
-
end
|
|
564
|
-
end
|
|
565
|
-
|
|
566
|
-
test "to_param should use new slug if existing record changes successfully" do
|
|
567
|
-
transaction do
|
|
568
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
569
|
-
assert journalist.save
|
|
570
|
-
journalist.name = "Superman"
|
|
571
|
-
journalist.slug = nil
|
|
572
|
-
assert journalist.save
|
|
573
|
-
assert_equal "superman", journalist.to_param
|
|
574
|
-
end
|
|
575
|
-
end
|
|
576
|
-
|
|
577
|
-
test "to_param should use new slug within callbacks if new record is saved successfully" do
|
|
578
|
-
transaction do
|
|
579
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
580
|
-
assert journalist.save
|
|
581
|
-
assert_equal "clark-kent", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
|
582
|
-
end
|
|
583
|
-
end
|
|
584
|
-
|
|
585
|
-
test "to_param should use new slug within callbacks if existing record changes successfully" do
|
|
586
|
-
transaction do
|
|
587
|
-
journalist = Journalist.new name: "Clark Kent", active: true
|
|
588
|
-
assert journalist.save
|
|
589
|
-
assert journalist.valid?
|
|
590
|
-
journalist.name = "Superman"
|
|
591
|
-
journalist.slug = nil
|
|
592
|
-
assert journalist.save, "save should be successful"
|
|
593
|
-
assert_equal "superman", journalist.to_param_in_callback, "value of to_param in callback should use the new slug value"
|
|
594
|
-
end
|
|
595
|
-
end
|
|
596
|
-
end
|
|
597
|
-
|
|
598
|
-
class ConfigurableRoutesTest < TestCaseClass
|
|
599
|
-
include FriendlyId::Test
|
|
600
|
-
|
|
601
|
-
class Article < ActiveRecord::Base
|
|
602
|
-
extend FriendlyId
|
|
603
|
-
|
|
604
|
-
friendly_id :name, use: :slugged, routes: :friendly
|
|
605
|
-
end
|
|
606
|
-
|
|
607
|
-
class Novel < ActiveRecord::Base
|
|
608
|
-
extend FriendlyId
|
|
609
|
-
|
|
610
|
-
friendly_id :name, use: :slugged, routes: :default
|
|
611
|
-
end
|
|
612
|
-
|
|
613
|
-
test "to_param should return a friendly id when the routes option is set to :friendly" do
|
|
614
|
-
transaction do
|
|
615
|
-
article = Article.create! name: "Titanic Hits; Iceberg Sinks"
|
|
616
|
-
|
|
617
|
-
assert_equal "titanic-hits-iceberg-sinks", article.to_param
|
|
618
|
-
end
|
|
619
|
-
end
|
|
620
|
-
|
|
621
|
-
test "to_param should return the id when the routes option is set to anything but friendly" do
|
|
622
|
-
transaction do
|
|
623
|
-
novel = Novel.create! name: "Don Quixote"
|
|
624
|
-
|
|
625
|
-
assert_equal novel.id.to_s, novel.to_param
|
|
626
|
-
end
|
|
627
|
-
end
|
|
628
|
-
end
|