friendly_id 5.0.0.beta1 → 5.0.0.beta2
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/CONTRIBUTING.md +5 -0
- data/Guide.md +63 -5
- data/README.md +15 -8
- data/Rakefile +1 -0
- data/bench.rb +14 -1
- data/lib/friendly_id.rb +2 -1
- data/lib/friendly_id/base.rb +3 -3
- data/lib/friendly_id/configuration.rb +2 -2
- data/lib/friendly_id/finder_methods.rb +50 -0
- data/lib/friendly_id/finders.rb +48 -37
- data/lib/friendly_id/history.rb +11 -5
- data/lib/friendly_id/slugged.rb +13 -5
- data/lib/friendly_id/version.rb +2 -2
- data/test/finders_test.rb +29 -0
- data/test/history_test.rb +31 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dec251b305da7b006b6d849ae54f04fab7ef7b7a
|
4
|
+
data.tar.gz: c7211733816c992c5ce91d5fea8ca8de2d12552d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ae8a30684b5081c38453dd908a10347071da7456338cb6c1f65fa040918ab970ffe88900e54cecadddb58c56e5f4133221421aa1e48b6b12c8ee2c43a095f2f
|
7
|
+
data.tar.gz: 786a072ec3e57cc9ba785b5d175adb2934d70157e0f93367bbd1a3664211f2150853622b51123dcac66893ae79b98565f9367c69a599e9d5d67db8aa13159502
|
data/CONTRIBUTING.md
CHANGED
@@ -16,6 +16,11 @@ Here are the answers to some common questions.
|
|
16
16
|
Then you **must** use FriendlyId 5, which is currently available in the master
|
17
17
|
branch of the repository, and will be released to Rubygems soon.
|
18
18
|
|
19
|
+
### I'm seeing a bunch of odd characters at the end of the id
|
20
|
+
|
21
|
+
For example: `2bc08962-b3dd-4f29-b2e6-244710c86106`. FriendlyId 5 uses a UUID
|
22
|
+
rather than a sequence to simplify slug generation and avoid concurrency problems.
|
23
|
+
|
19
24
|
### How do I set up my routes for FriendlyId?
|
20
25
|
|
21
26
|
Exactly like in any other Rails app. FriendlyId doesn't change any routing
|
data/Guide.md
CHANGED
@@ -83,6 +83,56 @@ Writing the code to process an arbitrary string into a good identifier for use
|
|
83
83
|
in a URL can be repetitive and surprisingly tricky, so for this reason it's
|
84
84
|
often better and easier to use {FriendlyId::Slugged slugs}.
|
85
85
|
|
86
|
+
## Performing Finds with FriendlyId
|
87
|
+
|
88
|
+
FriendlyId offers enhanced finders which will search for your record by
|
89
|
+
friendly id, and fall back to the numeric id if necessary. This makes it easy
|
90
|
+
to add FriendlyId to an existing application with minimal code modification.
|
91
|
+
|
92
|
+
By default, these methods are available only on the `friendly` scope:
|
93
|
+
|
94
|
+
Restaurant.friendly.find('plaza-diner') #=> works
|
95
|
+
Restaurant.friendly.find(23) #=> also works
|
96
|
+
Restaurant.find(23) #=> still works
|
97
|
+
Restaurant.find('plaza-diner') #=> will not work
|
98
|
+
|
99
|
+
### Restoring FriendlyId 4.0-style finders
|
100
|
+
|
101
|
+
Prior to version 5.0, FriendlyId overrode the default finder methods to perform
|
102
|
+
friendly finds all the time. This required modifying parts of Rails that did
|
103
|
+
not have a public API, which was harder to maintain and at times caused
|
104
|
+
compatiblity problems. In 5.0 we decided change the library's defaults and add
|
105
|
+
the friendly finder methods only to the `friendly` scope in order to boost
|
106
|
+
compatiblity. However, you can still opt-in to original functionality very
|
107
|
+
easily by using the `:finders` addon:
|
108
|
+
|
109
|
+
class Restaurant < ActiveRecord::Base
|
110
|
+
extend FriendlyId
|
111
|
+
|
112
|
+
scope :active, -> {where(:active => true)}
|
113
|
+
|
114
|
+
friendly_id :name, :use => [:slugged, :finders]
|
115
|
+
end
|
116
|
+
|
117
|
+
Restaurant.friendly.find('plaza-diner') #=> works
|
118
|
+
Restaurant.find('plaza-diner') #=> now also works
|
119
|
+
Restaurant.active.find('plaza-diner') #=> now also works
|
120
|
+
|
121
|
+
### Updating your application to use FriendlyId's finders
|
122
|
+
|
123
|
+
Unless you've chosen to use the `:finders` addon, be sure to modify the finders
|
124
|
+
in your controllers to use the `friendly` scope. For example:
|
125
|
+
|
126
|
+
# before
|
127
|
+
def set_restaurant
|
128
|
+
@restaurant = Restaurant.find(params[:id])
|
129
|
+
end
|
130
|
+
|
131
|
+
# after
|
132
|
+
def set_restaurant
|
133
|
+
@restaurant = Restaurant.friendly.find(params[:id])
|
134
|
+
end
|
135
|
+
|
86
136
|
|
87
137
|
## Slugged Models
|
88
138
|
|
@@ -241,12 +291,8 @@ whether for a single slug or for slug candidates.
|
|
241
291
|
|
242
292
|
#### Deciding When to Generate New Slugs
|
243
293
|
|
244
|
-
Previous versions of FriendlyId provided a method named
|
245
|
-
`should_generate_new_friendly_id?` which you could override to control when new
|
246
|
-
slugs were generated.
|
247
|
-
|
248
294
|
As of FriendlyId 5.0, slugs are only generated when the `slug` field is nil. If
|
249
|
-
you want a slug to be regenerated,
|
295
|
+
you want a slug to be regenerated,set the slug field to nil:
|
250
296
|
|
251
297
|
restaurant.friendly_id # joes-diner
|
252
298
|
restaurant.name = "The Plaza Diner"
|
@@ -256,6 +302,18 @@ you want a slug to be regenerated, you must explicity set the field to nil:
|
|
256
302
|
restaurant.save!
|
257
303
|
restaurant.friendly_id # the-plaza-diner
|
258
304
|
|
305
|
+
You can also override the
|
306
|
+
{FriendlyId::Slugged#should_generate_new_friendly_id?} method, which lets you
|
307
|
+
control exactly when new friendly ids are set:
|
308
|
+
|
309
|
+
class Post < ActiveRecord::Base
|
310
|
+
extend FriendlyId
|
311
|
+
friendly_id :title, :use => :slugged
|
312
|
+
|
313
|
+
def should_generate_new_friendly_id?
|
314
|
+
title_changed?
|
315
|
+
end
|
316
|
+
end
|
259
317
|
|
260
318
|
#### Locale-specific Transliterations
|
261
319
|
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
[](https://travis-ci.org/norman/friendly_id)
|
2
2
|
|
3
3
|
**VERSION NOTE**
|
4
4
|
|
@@ -11,7 +11,9 @@ If you wish to use this gem with Rails 3.1 or 3.2 you need to use FriendlyId ver
|
|
11
11
|
Please see [4.0-stable
|
12
12
|
branch](https://github.com/norman/friendly_id/tree/4.0-stable).
|
13
13
|
|
14
|
-
|
14
|
+
# FriendlyId
|
15
|
+
|
16
|
+
<em>For the most complete, user-friendly documentation, see the [FriendlyId Guide](http://rubydoc.info/github/norman/friendly_id/master/file/Guide.md).</em>
|
15
17
|
|
16
18
|
FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
|
17
19
|
Ruby on Rails. It allows you to create pretty URLs and work with human-friendly
|
@@ -43,8 +45,15 @@ with 4.x.
|
|
43
45
|
|
44
46
|
Here's a summary of the most important changes:
|
45
47
|
|
46
|
-
* FriendlyId no longer overrides `find
|
47
|
-
must do `Model.friendly.find` rather than `Model.find`.
|
48
|
+
* FriendlyId no longer overrides `find` by default. If you want to do friendly finds,
|
49
|
+
you must do `Model.friendly.find` rather than `Model.find`. You can however easily
|
50
|
+
restore FriendlyId 4-style finders by using the `:finders` addon:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
friendly_id :foo, use: :slugged # you must do MyClass.friendly.find('bar')
|
54
|
+
# or...
|
55
|
+
friendly_id :foo, use: [:slugged, :finders] # you can now do MyClass.find('bar')
|
56
|
+
```
|
48
57
|
|
49
58
|
* Version 5.0 offers a new "candidates" functionality which makes it easy to
|
50
59
|
set up a list of alternate slugs that can be used to uniquely distinguish
|
@@ -69,13 +78,11 @@ end
|
|
69
78
|
```
|
70
79
|
|
71
80
|
* Now that candidates have been added, FriendlyId no longer uses a numeric
|
72
|
-
sequence to differentiate conflicting slug, but rather a
|
81
|
+
sequence to differentiate conflicting slug, but rather a UUID (e.g. something
|
82
|
+
like `2bc08962-b3dd-4f29-b2e6-244710c86106`). This makes the
|
73
83
|
codebase simpler and more reliable when running concurrently, at the expense
|
74
84
|
of uglier ids being generated when there are conflicts.
|
75
85
|
|
76
|
-
* The Globalize module has been removed and will be released as its own gem.
|
77
|
-
Note that it has not yet been developed.
|
78
|
-
|
79
86
|
* The default sequence separator is now `-` rather than `--`.
|
80
87
|
|
81
88
|
* Slugs are no longer regenerated when a record is saved. If you want to regenerate
|
data/Rakefile
CHANGED
@@ -48,6 +48,7 @@ task :guide do
|
|
48
48
|
|
49
49
|
buffer << read_comments("lib/friendly_id.rb")
|
50
50
|
buffer << read_comments("lib/friendly_id/base.rb")
|
51
|
+
buffer << read_comments("lib/friendly_id/finders.rb")
|
51
52
|
buffer << read_comments("lib/friendly_id/slugged.rb")
|
52
53
|
buffer << read_comments("lib/friendly_id/history.rb")
|
53
54
|
buffer << read_comments("lib/friendly_id/scoped.rb")
|
data/bench.rb
CHANGED
@@ -25,15 +25,24 @@ class Manual < ActiveRecord::Base
|
|
25
25
|
friendly_id :name, :use => :history
|
26
26
|
end
|
27
27
|
|
28
|
+
class Restaurant < ActiveRecord::Base
|
29
|
+
extend FriendlyId
|
30
|
+
relation.class.send(:include, FriendlyId::FinderMethods)
|
31
|
+
friendly_id :name
|
32
|
+
end
|
33
|
+
|
34
|
+
|
28
35
|
BOOKS = []
|
29
36
|
JOURNALISTS = []
|
30
37
|
MANUALS = []
|
38
|
+
RESTAURANTS = []
|
31
39
|
|
32
40
|
100.times do
|
33
41
|
name = Faker::Name.name
|
34
42
|
BOOKS << (Book.create! :name => name).id
|
35
43
|
JOURNALISTS << (Journalist.create! :name => name).friendly_id
|
36
44
|
MANUALS << (Manual.create! :name => name).friendly_id
|
45
|
+
RESTAURANTS << (Restaurant.create! :name => name).friendly_id
|
37
46
|
end
|
38
47
|
|
39
48
|
ActiveRecord::Base.connection.execute "UPDATE manuals SET slug = NULL"
|
@@ -47,6 +56,10 @@ Benchmark.bmbm do |x|
|
|
47
56
|
N.times {Journalist.friendly.find JOURNALISTS.rand}
|
48
57
|
end
|
49
58
|
|
59
|
+
x.report 'find (in-table slug; included FinderMethods)' do
|
60
|
+
N.times {Restaurant.find RESTAURANTS.rand}
|
61
|
+
end
|
62
|
+
|
50
63
|
x.report 'find (external slug)' do
|
51
64
|
N.times {Manual.friendly.find MANUALS.rand}
|
52
65
|
end
|
@@ -62,4 +75,4 @@ Benchmark.bmbm do |x|
|
|
62
75
|
x.report 'insert (external slug)' do
|
63
76
|
N.times {transaction {Manual.create :name => Faker::Name.name}}
|
64
77
|
end
|
65
|
-
end
|
78
|
+
end
|
data/lib/friendly_id.rb
CHANGED
@@ -3,7 +3,7 @@ require "thread"
|
|
3
3
|
require "friendly_id/base"
|
4
4
|
require "friendly_id/object_utils"
|
5
5
|
require "friendly_id/configuration"
|
6
|
-
require "friendly_id/
|
6
|
+
require "friendly_id/finder_methods"
|
7
7
|
|
8
8
|
=begin
|
9
9
|
|
@@ -51,6 +51,7 @@ module FriendlyId
|
|
51
51
|
autoload :Reserved, "friendly_id/reserved"
|
52
52
|
autoload :Scoped, "friendly_id/scoped"
|
53
53
|
autoload :Slugged, "friendly_id/slugged"
|
54
|
+
autoload :Finders, "friendly_id/finders"
|
54
55
|
|
55
56
|
# FriendlyId takes advantage of `extended` to do basic model setup, primarily
|
56
57
|
# extending {FriendlyId::Base} to add {FriendlyId::Base#friendly_id
|
data/lib/friendly_id/base.rb
CHANGED
@@ -191,8 +191,8 @@ often better and easier to use {FriendlyId::Slugged slugs}.
|
|
191
191
|
include Model
|
192
192
|
end
|
193
193
|
|
194
|
-
#
|
195
|
-
# @see FriendlyId::
|
194
|
+
# Returns a scope that includes the friendly finders.
|
195
|
+
# @see FriendlyId::FinderMethods
|
196
196
|
def friendly
|
197
197
|
# Guess what? This causes Rails to invoke `extend` on the scope, which has
|
198
198
|
# the well-known effect of blowing away Ruby's method cache. It would be
|
@@ -203,7 +203,7 @@ often better and easier to use {FriendlyId::Slugged slugs}.
|
|
203
203
|
# and maintainability. If you'd like to improve the performance, your
|
204
204
|
# efforts would be best directed at improving it at the root cause
|
205
205
|
# of the problem - in Rails - because it would benefit more people.
|
206
|
-
all.extending(
|
206
|
+
all.extending(FinderMethods)
|
207
207
|
end
|
208
208
|
|
209
209
|
# Returns the model class's {FriendlyId::Configuration friendly_id_config}.
|
@@ -67,7 +67,7 @@ module FriendlyId
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
# Returns whether the given module is in use
|
70
|
+
# Returns whether the given module is in use.
|
71
71
|
def uses?(mod)
|
72
72
|
@model_class < get_module(mod)
|
73
73
|
end
|
@@ -84,7 +84,7 @@ module FriendlyId
|
|
84
84
|
private
|
85
85
|
|
86
86
|
def get_module(object)
|
87
|
-
Module === object ? object : FriendlyId.const_get(object.to_s.
|
87
|
+
Module === object ? object : FriendlyId.const_get(object.to_s.titleize.camelize.gsub(/\s+/, ''))
|
88
88
|
end
|
89
89
|
|
90
90
|
def set(values)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module FriendlyId
|
2
|
+
|
3
|
+
module FinderMethods
|
4
|
+
|
5
|
+
# Finds a record using the given id.
|
6
|
+
#
|
7
|
+
# If the id is "unfriendly", it will call the original find method.
|
8
|
+
# If the id is a numeric string like '123' it will first look for a friendly
|
9
|
+
# id matching '123' and then fall back to looking for a record with the
|
10
|
+
# numeric id '123'.
|
11
|
+
#
|
12
|
+
# Since FriendlyId 5.0, if the id is a numeric string like '123-foo' it
|
13
|
+
# will *only* search by friendly id and not fall back to the regular find
|
14
|
+
# method.
|
15
|
+
#
|
16
|
+
# If you want to search only by the friendly id, use {#find_by_friendly_id}.
|
17
|
+
# @raise ActiveRecord::RecordNotFound
|
18
|
+
def find(*args)
|
19
|
+
id = args.first
|
20
|
+
return super if args.count != 1 || id.unfriendly_id?
|
21
|
+
first_by_friendly_id(id).tap {|result| return result unless result.nil?}
|
22
|
+
return super if Integer(id, 10) rescue nil
|
23
|
+
raise ActiveRecord::RecordNotFound
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns true if a record with the given id exists.
|
27
|
+
def exists?(conditions = :none)
|
28
|
+
return super unless conditions.friendly_id?
|
29
|
+
exists_by_friendly_id?(conditions)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Finds exclusively by the friendly id, completely bypassing original
|
33
|
+
# `find`.
|
34
|
+
# @raise ActiveRecord::RecordNotFound
|
35
|
+
def find_by_friendly_id(id)
|
36
|
+
first_by_friendly_id(id) or raise ActiveRecord::RecordNotFound
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def first_by_friendly_id(id)
|
42
|
+
where(friendly_id_config.query_field => id).first
|
43
|
+
end
|
44
|
+
|
45
|
+
def exists_by_friendly_id?(id)
|
46
|
+
where(friendly_id_config.query_field => id).exists?
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
data/lib/friendly_id/finders.rb
CHANGED
@@ -1,51 +1,62 @@
|
|
1
1
|
module FriendlyId
|
2
|
+
=begin
|
3
|
+
## Performing Finds with FriendlyId
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
FriendlyId offers enhanced finders which will search for your record by
|
6
|
+
friendly id, and fall back to the numeric id if necessary. This makes it easy
|
7
|
+
to add FriendlyId to an existing application with minimal code modification.
|
5
8
|
|
6
|
-
|
7
|
-
#
|
8
|
-
# If the id is "unfriendly", it will call the original find method.
|
9
|
-
# If the id is a numeric string like '123' it will first look for a friendly
|
10
|
-
# id matching '123' and then fall back to looking for a record with the
|
11
|
-
# numeric id '123'.
|
12
|
-
#
|
13
|
-
# Since FriendlyId 5.0, if the id is a numeric string like '123-foo' it
|
14
|
-
# will *only* search by friendly id and not fall back to the regular find
|
15
|
-
# method.
|
16
|
-
#
|
17
|
-
# If you want to search only by the friendly id, use {#find_by_friendly_id}.
|
18
|
-
# @raise ActiveRecord::RecordNotFound
|
19
|
-
def find(*args)
|
20
|
-
id = args.first
|
21
|
-
return super if args.count != 1 || id.unfriendly_id?
|
22
|
-
first_by_friendly_id(id).tap {|result| return result unless result.nil?}
|
23
|
-
return super if Integer(id, 10) rescue nil
|
24
|
-
raise ActiveRecord::RecordNotFound
|
25
|
-
end
|
9
|
+
By default, these methods are available only on the `friendly` scope:
|
26
10
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
11
|
+
Restaurant.friendly.find('plaza-diner') #=> works
|
12
|
+
Restaurant.friendly.find(23) #=> also works
|
13
|
+
Restaurant.find(23) #=> still works
|
14
|
+
Restaurant.find('plaza-diner') #=> will not work
|
15
|
+
|
16
|
+
### Restoring FriendlyId 4.0-style finders
|
17
|
+
|
18
|
+
Prior to version 5.0, FriendlyId overrode the default finder methods to perform
|
19
|
+
friendly finds all the time. This required modifying parts of Rails that did
|
20
|
+
not have a public API, which was harder to maintain and at times caused
|
21
|
+
compatiblity problems. In 5.0 we decided change the library's defaults and add
|
22
|
+
the friendly finder methods only to the `friendly` scope in order to boost
|
23
|
+
compatiblity. However, you can still opt-in to original functionality very
|
24
|
+
easily by using the `:finders` addon:
|
25
|
+
|
26
|
+
class Restaurant < ActiveRecord::Base
|
27
|
+
extend FriendlyId
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def find_by_friendly_id(id)
|
37
|
-
first_by_friendly_id(id) or raise ActiveRecord::RecordNotFound
|
29
|
+
scope :active, -> {where(:active => true)}
|
30
|
+
|
31
|
+
friendly_id :name, :use => [:slugged, :finders]
|
38
32
|
end
|
39
33
|
|
40
|
-
|
34
|
+
Restaurant.friendly.find('plaza-diner') #=> works
|
35
|
+
Restaurant.find('plaza-diner') #=> now also works
|
36
|
+
Restaurant.active.find('plaza-diner') #=> now also works
|
37
|
+
|
38
|
+
### Updating your application to use FriendlyId's finders
|
39
|
+
|
40
|
+
Unless you've chosen to use the `:finders` addon, be sure to modify the finders
|
41
|
+
in your controllers to use the `friendly` scope. For example:
|
41
42
|
|
42
|
-
|
43
|
-
|
43
|
+
# before
|
44
|
+
def set_restaurant
|
45
|
+
@restaurant = Restaurant.find(params[:id])
|
44
46
|
end
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
+
# after
|
49
|
+
def set_restaurant
|
50
|
+
@restaurant = Restaurant.friendly.find(params[:id])
|
48
51
|
end
|
52
|
+
=end
|
53
|
+
module Finders
|
54
|
+
def self.included(model_class)
|
55
|
+
model_class.send(:relation).class.send(:include, FriendlyId::FinderMethods)
|
49
56
|
|
57
|
+
if model_class.friendly_id_config.uses? :history
|
58
|
+
model_class.send(:relation).class.send(:include, FriendlyId::History::HistoryFinderMethods)
|
59
|
+
end
|
60
|
+
end
|
50
61
|
end
|
51
62
|
end
|
data/lib/friendly_id/history.rb
CHANGED
@@ -54,27 +54,33 @@ method.
|
|
54
54
|
=end
|
55
55
|
module History
|
56
56
|
|
57
|
+
def self.setup(model_class)
|
58
|
+
model_class.friendly_id_config.use :slugged
|
59
|
+
end
|
60
|
+
|
57
61
|
# Configures the model instance to use the History add-on.
|
58
62
|
def self.included(model_class)
|
59
63
|
model_class.class_eval do
|
60
|
-
@friendly_id_config.use :slugged
|
61
|
-
|
62
64
|
has_many :slugs, -> {order("#{Slug.quoted_table_name}.id DESC")}, {
|
63
65
|
:as => :sluggable,
|
64
66
|
:dependent => :destroy,
|
65
67
|
:class_name => Slug.to_s
|
66
68
|
}
|
67
69
|
|
70
|
+
if model_class.friendly_id_config.uses? :finders
|
71
|
+
model_class.send(:relation).class.send(:include, HistoryFinderMethods)
|
72
|
+
end
|
73
|
+
|
68
74
|
after_save :create_slug
|
69
75
|
|
70
76
|
def self.friendly
|
71
|
-
all.extending(
|
77
|
+
all.extending(HistoryFinderMethods)
|
72
78
|
end
|
73
79
|
end
|
74
80
|
end
|
75
81
|
|
76
|
-
module
|
77
|
-
include
|
82
|
+
module HistoryFinderMethods
|
83
|
+
include FinderMethods
|
78
84
|
|
79
85
|
private
|
80
86
|
|
data/lib/friendly_id/slugged.rb
CHANGED
@@ -162,12 +162,8 @@ whether for a single slug or for slug candidates.
|
|
162
162
|
|
163
163
|
#### Deciding When to Generate New Slugs
|
164
164
|
|
165
|
-
Previous versions of FriendlyId provided a method named
|
166
|
-
`should_generate_new_friendly_id?` which you could override to control when new
|
167
|
-
slugs were generated.
|
168
|
-
|
169
165
|
As of FriendlyId 5.0, slugs are only generated when the `slug` field is nil. If
|
170
|
-
you want a slug to be regenerated,
|
166
|
+
you want a slug to be regenerated,set the slug field to nil:
|
171
167
|
|
172
168
|
restaurant.friendly_id # joes-diner
|
173
169
|
restaurant.name = "The Plaza Diner"
|
@@ -177,6 +173,18 @@ you want a slug to be regenerated, you must explicity set the field to nil:
|
|
177
173
|
restaurant.save!
|
178
174
|
restaurant.friendly_id # the-plaza-diner
|
179
175
|
|
176
|
+
You can also override the
|
177
|
+
{FriendlyId::Slugged#should_generate_new_friendly_id?} method, which lets you
|
178
|
+
control exactly when new friendly ids are set:
|
179
|
+
|
180
|
+
class Post < ActiveRecord::Base
|
181
|
+
extend FriendlyId
|
182
|
+
friendly_id :title, :use => :slugged
|
183
|
+
|
184
|
+
def should_generate_new_friendly_id?
|
185
|
+
title_changed?
|
186
|
+
end
|
187
|
+
end
|
180
188
|
|
181
189
|
#### Locale-specific Transliterations
|
182
190
|
|
data/lib/friendly_id/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module FriendlyId
|
2
|
-
VERSION = "5.0.0.
|
3
|
-
end
|
2
|
+
VERSION = "5.0.0.beta2"
|
3
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class JournalistWithFriendlyFinders < ActiveRecord::Base
|
4
|
+
self.table_name = 'journalists'
|
5
|
+
extend FriendlyId
|
6
|
+
scope :existing, -> {where('1 = 1')}
|
7
|
+
friendly_id :name, use: [:slugged, :finders]
|
8
|
+
end
|
9
|
+
|
10
|
+
class Finders < MiniTest::Unit::TestCase
|
11
|
+
|
12
|
+
include FriendlyId::Test
|
13
|
+
|
14
|
+
def model_class
|
15
|
+
JournalistWithFriendlyFinders
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'should find records with finders as class methods' do
|
19
|
+
with_instance_of(model_class) do |record|
|
20
|
+
assert model_class.find(record.friendly_id)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test 'should find records with finders on relations' do
|
25
|
+
with_instance_of(model_class) do |record|
|
26
|
+
assert model_class.existing.find(record.friendly_id)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/test/history_test.rb
CHANGED
@@ -136,6 +136,37 @@ class HistoryTestWithSti < HistoryTest
|
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
|
+
class HistoryTestWithFriendlyFinders < HistoryTest
|
140
|
+
class Journalist < ActiveRecord::Base
|
141
|
+
extend FriendlyId
|
142
|
+
friendly_id :name, :use => [:slugged, :finders, :history]
|
143
|
+
end
|
144
|
+
|
145
|
+
class Restaurant < ActiveRecord::Base
|
146
|
+
extend FriendlyId
|
147
|
+
belongs_to :city
|
148
|
+
friendly_id :name, :use => [:slugged, :history, :finders]
|
149
|
+
end
|
150
|
+
|
151
|
+
|
152
|
+
test "should be findable by old slugs" do
|
153
|
+
[Journalist, Restaurant].each do |model_class|
|
154
|
+
with_instance_of(model_class) do |record|
|
155
|
+
old_friendly_id = record.friendly_id
|
156
|
+
record.name = record.name + "b"
|
157
|
+
record.slug = nil
|
158
|
+
record.save!
|
159
|
+
begin
|
160
|
+
assert model_class.find(old_friendly_id)
|
161
|
+
assert model_class.exists?(old_friendly_id), "should exist? by old id"
|
162
|
+
rescue ActiveRecord::RecordNotFound
|
163
|
+
flunk "Could not find record by old id"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
139
170
|
class City < ActiveRecord::Base
|
140
171
|
has_many :restaurants
|
141
172
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: friendly_id
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.0.0.
|
4
|
+
version: 5.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Norman Clarke
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-08-
|
12
|
+
date: 2013-08-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -167,6 +167,7 @@ files:
|
|
167
167
|
- lib/friendly_id/base.rb
|
168
168
|
- lib/friendly_id/candidates.rb
|
169
169
|
- lib/friendly_id/configuration.rb
|
170
|
+
- lib/friendly_id/finder_methods.rb
|
170
171
|
- lib/friendly_id/finders.rb
|
171
172
|
- lib/friendly_id/history.rb
|
172
173
|
- lib/friendly_id/migration.rb
|
@@ -188,6 +189,7 @@ files:
|
|
188
189
|
- test/configuration_test.rb
|
189
190
|
- test/core_test.rb
|
190
191
|
- test/databases.yml
|
192
|
+
- test/finders_test.rb
|
191
193
|
- test/generator_test.rb
|
192
194
|
- test/helper.rb
|
193
195
|
- test/history_test.rb
|