friendly_id 5.0.0.beta1 → 5.0.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://travis-ci.org/norman/friendly_id.png)](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
|