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.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.github/dependabot.yml +6 -0
  4. data/.github/workflows/test.yml +34 -25
  5. data/Changelog.md +6 -0
  6. data/Gemfile +9 -13
  7. data/README.md +21 -0
  8. data/Rakefile +24 -27
  9. data/bench.rb +30 -27
  10. data/certs/parndt.pem +25 -23
  11. data/friendly_id.gemspec +26 -29
  12. data/gemfiles/Gemfile.rails-5.2.rb +11 -16
  13. data/gemfiles/Gemfile.rails-6.0.rb +11 -16
  14. data/gemfiles/Gemfile.rails-6.1.rb +22 -0
  15. data/gemfiles/Gemfile.rails-7.0.rb +22 -0
  16. data/guide.rb +5 -5
  17. data/lib/friendly_id/base.rb +57 -60
  18. data/lib/friendly_id/candidates.rb +9 -11
  19. data/lib/friendly_id/configuration.rb +6 -7
  20. data/lib/friendly_id/finder_methods.rb +26 -11
  21. data/lib/friendly_id/finders.rb +63 -66
  22. data/lib/friendly_id/history.rb +59 -63
  23. data/lib/friendly_id/initializer.rb +4 -4
  24. data/lib/friendly_id/migration.rb +6 -6
  25. data/lib/friendly_id/object_utils.rb +2 -2
  26. data/lib/friendly_id/reserved.rb +28 -32
  27. data/lib/friendly_id/scoped.rb +97 -102
  28. data/lib/friendly_id/sequentially_slugged/calculator.rb +69 -0
  29. data/lib/friendly_id/sequentially_slugged.rb +17 -64
  30. data/lib/friendly_id/simple_i18n.rb +75 -69
  31. data/lib/friendly_id/slug.rb +1 -2
  32. data/lib/friendly_id/slug_generator.rb +1 -3
  33. data/lib/friendly_id/slugged.rb +234 -238
  34. data/lib/friendly_id/version.rb +1 -1
  35. data/lib/friendly_id.rb +41 -45
  36. data/lib/generators/friendly_id_generator.rb +9 -9
  37. data/test/base_test.rb +10 -13
  38. data/test/benchmarks/finders.rb +28 -26
  39. data/test/benchmarks/object_utils.rb +13 -13
  40. data/test/candidates_test.rb +17 -18
  41. data/test/configuration_test.rb +7 -11
  42. data/test/core_test.rb +1 -2
  43. data/test/databases.yml +4 -3
  44. data/test/finders_test.rb +52 -5
  45. data/test/generator_test.rb +16 -26
  46. data/test/helper.rb +29 -22
  47. data/test/history_test.rb +70 -74
  48. data/test/numeric_slug_test.rb +4 -4
  49. data/test/object_utils_test.rb +0 -2
  50. data/test/reserved_test.rb +9 -11
  51. data/test/schema.rb +5 -4
  52. data/test/scoped_test.rb +18 -20
  53. data/test/sequentially_slugged_test.rb +65 -50
  54. data/test/shared.rb +15 -16
  55. data/test/simple_i18n_test.rb +22 -12
  56. data/test/slugged_test.rb +102 -121
  57. data/test/sti_test.rb +19 -21
  58. data.tar.gz.sig +0 -0
  59. metadata +35 -30
  60. metadata.gz.sig +1 -1
@@ -1,251 +1,247 @@
1
- # encoding: utf-8
2
1
  require "friendly_id/slug_generator"
3
2
  require "friendly_id/candidates"
4
3
 
5
4
  module FriendlyId
6
- =begin
7
-
8
- ## Slugged Models
9
-
10
- FriendlyId can use a separate column to store slugs for models which require
11
- some text processing.
12
-
13
- For example, blog applications typically use a post title to provide the basis
14
- of a search engine friendly URL. Such identifiers typically lack uppercase
15
- characters, use ASCII to approximate UTF-8 characters, and strip out other
16
- characters which may make them aesthetically unappealing or error-prone when
17
- used in a URL.
18
-
19
- class Post < ActiveRecord::Base
20
- extend FriendlyId
21
- friendly_id :title, :use => :slugged
22
- end
23
-
24
- @post = Post.create(:title => "This is the first post!")
25
- @post.friendly_id # returns "this-is-the-first-post"
26
- redirect_to @post # the URL will be /posts/this-is-the-first-post
27
-
28
- In general, use slugs by default unless you know for sure you don't need them.
29
- To activate the slugging functionality, use the {FriendlyId::Slugged} module.
30
-
31
- FriendlyId will generate slugs from a method or column that you specify, and
32
- store them in a field in your model. By default, this field must be named
33
- `:slug`, though you may change this using the
34
- {FriendlyId::Slugged::Configuration#slug_column slug_column} configuration
35
- option. You should add an index to this column, and in most cases, make it
36
- unique. You may also wish to constrain it to NOT NULL, but this depends on your
37
- app's behavior and requirements.
38
-
39
- ### Example Setup
40
-
41
- # your model
42
- class Post < ActiveRecord::Base
43
- extend FriendlyId
44
- friendly_id :title, :use => :slugged
45
- validates_presence_of :title, :slug, :body
46
- end
47
-
48
- # a migration
49
- class CreatePosts < ActiveRecord::Migration
50
- def self.up
51
- create_table :posts do |t|
52
- t.string :title, :null => false
53
- t.string :slug, :null => false
54
- t.text :body
55
- end
56
-
57
- add_index :posts, :slug, :unique => true
58
- end
59
-
60
- def self.down
61
- drop_table :posts
62
- end
63
- end
64
-
65
- ### Working With Slugs
66
-
67
- #### Formatting
68
-
69
- By default, FriendlyId uses Active Support's
70
- [parameterize](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize)
71
- method to create slugs. This method will intelligently replace spaces with
72
- dashes, and Unicode Latin characters with ASCII approximations:
73
-
74
- movie = Movie.create! :title => "Der Preis fürs Überleben"
75
- movie.slug #=> "der-preis-furs-uberleben"
76
-
77
- #### Column or Method?
78
-
79
- FriendlyId always uses a method as the basis of the slug text - not a column. At
80
- first glance, this may sound confusing, but remember that Active Record provides
81
- methods for each column in a model's associated table, and that's what
82
- FriendlyId uses.
83
-
84
- Here's an example of a class that uses a custom method to generate the slug:
85
-
86
- class Person < ActiveRecord::Base
87
- extend FriendlyId
88
- friendly_id :name_and_location, use: :slugged
89
-
90
- def name_and_location
91
- "#{name} from #{location}"
92
- end
93
- end
94
-
95
- bob = Person.create! :name => "Bob Smith", :location => "New York City"
96
- bob.friendly_id #=> "bob-smith-from-new-york-city"
97
-
98
- FriendlyId refers to this internally as the "base" method.
99
-
100
- #### Uniqueness
101
-
102
- When you try to insert a record that would generate a duplicate friendly id,
103
- FriendlyId will append a UUID to the generated slug to ensure uniqueness:
104
-
105
- car = Car.create :title => "Peugeot 206"
106
- car2 = Car.create :title => "Peugeot 206"
107
-
108
- car.friendly_id #=> "peugeot-206"
109
- car2.friendly_id #=> "peugeot-206-f9f3789a-daec-4156-af1d-fab81aa16ee5"
110
-
111
- Previous versions of FriendlyId appended a numeric sequence to make slugs
112
- unique, but this was removed to simplify using FriendlyId in concurrent code.
113
-
114
- #### Candidates
115
-
116
- Since UUIDs are ugly, FriendlyId provides a "slug candidates" functionality to
117
- let you specify alternate slugs to use in the event the one you want to use is
118
- already taken. For example:
119
-
120
- class Restaurant < ActiveRecord::Base
121
- extend FriendlyId
122
- friendly_id :slug_candidates, use: :slugged
123
-
124
- # Try building a slug based on the following fields in
125
- # increasing order of specificity.
126
- def slug_candidates
127
- [
128
- :name,
129
- [:name, :city],
130
- [:name, :street, :city],
131
- [:name, :street_number, :street, :city]
132
- ]
133
- end
134
- end
135
-
136
- r1 = Restaurant.create! name: 'Plaza Diner', city: 'New Paltz'
137
- r2 = Restaurant.create! name: 'Plaza Diner', city: 'Kingston'
138
-
139
- r1.friendly_id #=> 'plaza-diner'
140
- r2.friendly_id #=> 'plaza-diner-kingston'
141
-
142
- To use candidates, make your FriendlyId base method return an array. The
143
- method need not be named `slug_candidates`; it can be anything you want. The
144
- array may contain any combination of symbols, strings, procs or lambdas and
145
- will be evaluated lazily and in order. If you include symbols, FriendlyId will
146
- invoke a method on your model class with the same name. Strings will be
147
- interpreted literally. Procs and lambdas will be called and their return values
148
- used as the basis of the friendly id. If none of the candidates can generate a
149
- unique slug, then FriendlyId will append a UUID to the first candidate as a
150
- last resort.
151
-
152
- #### Sequence Separator
153
-
154
- By default, FriendlyId uses a dash to separate the slug from a sequence.
155
-
156
- You can change this with the {FriendlyId::Slugged::Configuration#sequence_separator
157
- sequence_separator} configuration option.
158
-
159
- #### Providing Your Own Slug Processing Method
160
-
161
- You can override {FriendlyId::Slugged#normalize_friendly_id} in your model for
162
- total control over the slug format. It will be invoked for any generated slug,
163
- whether for a single slug or for slug candidates.
164
-
165
- #### Deciding When to Generate New Slugs
166
-
167
- As of FriendlyId 5.0, slugs are only generated when the `slug` field is nil. If
168
- you want a slug to be regenerated,set the slug field to nil:
169
-
170
- restaurant.friendly_id # joes-diner
171
- restaurant.name = "The Plaza Diner"
172
- restaurant.save!
173
- restaurant.friendly_id # joes-diner
174
- restaurant.slug = nil
175
- restaurant.save!
176
- restaurant.friendly_id # the-plaza-diner
177
-
178
- You can also override the
179
- {FriendlyId::Slugged#should_generate_new_friendly_id?} method, which lets you
180
- control exactly when new friendly ids are set:
181
-
182
- class Post < ActiveRecord::Base
183
- extend FriendlyId
184
- friendly_id :title, :use => :slugged
185
-
186
- def should_generate_new_friendly_id?
187
- title_changed?
188
- end
189
- end
190
-
191
- If you want to extend the default behavior but add your own conditions,
192
- don't forget to invoke `super` from your implementation:
193
-
194
- class Category < ActiveRecord::Base
195
- extend FriendlyId
196
- friendly_id :name, :use => :slugged
197
-
198
- def should_generate_new_friendly_id?
199
- name_changed? || super
200
- end
201
- end
202
-
203
- #### Locale-specific Transliterations
204
-
205
- Active Support's `parameterize` uses
206
- [transliterate](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate),
207
- which in turn can use I18n's transliteration rules to consider the current
208
- locale when replacing Latin characters:
209
-
210
- # config/locales/de.yml
211
- de:
212
- i18n:
213
- transliterate:
214
- rule:
215
- ü: "ue"
216
- ö: "oe"
217
- etc...
218
-
219
- movie = Movie.create! :title => "Der Preis fürs Überleben"
220
- movie.slug #=> "der-preis-fuers-ueberleben"
221
-
222
- This functionality was in fact taken from earlier versions of FriendlyId.
223
-
224
- #### Gotchas: Common Problems
225
-
226
- FriendlyId uses a before_validation callback to generate and set the slug. This
227
- means that if you create two model instances before saving them, it's possible
228
- they will generate the same slug, and the second save will fail.
229
-
230
- This can happen in two fairly normal cases: the first, when a model using nested
231
- attributes creates more than one record for a model that uses friendly_id. The
232
- second, in concurrent code, either in threads or multiple processes.
233
-
234
- To solve the nested attributes issue, I recommend simply avoiding them when
235
- creating more than one nested record for a model that uses FriendlyId. See [this
236
- Github issue](https://github.com/norman/friendly_id/issues/185) for discussion.
237
-
238
- =end
5
+ #
6
+ ## Slugged Models
7
+ #
8
+ # FriendlyId can use a separate column to store slugs for models which require
9
+ # some text processing.
10
+ #
11
+ # For example, blog applications typically use a post title to provide the basis
12
+ # of a search engine friendly URL. Such identifiers typically lack uppercase
13
+ # characters, use ASCII to approximate UTF-8 characters, and strip out other
14
+ # characters which may make them aesthetically unappealing or error-prone when
15
+ # used in a URL.
16
+ #
17
+ # class Post < ActiveRecord::Base
18
+ # extend FriendlyId
19
+ # friendly_id :title, :use => :slugged
20
+ # end
21
+ #
22
+ # @post = Post.create(:title => "This is the first post!")
23
+ # @post.friendly_id # returns "this-is-the-first-post"
24
+ # redirect_to @post # the URL will be /posts/this-is-the-first-post
25
+ #
26
+ # In general, use slugs by default unless you know for sure you don't need them.
27
+ # To activate the slugging functionality, use the {FriendlyId::Slugged} module.
28
+ #
29
+ # FriendlyId will generate slugs from a method or column that you specify, and
30
+ # store them in a field in your model. By default, this field must be named
31
+ # `:slug`, though you may change this using the
32
+ # {FriendlyId::Slugged::Configuration#slug_column slug_column} configuration
33
+ # option. You should add an index to this column, and in most cases, make it
34
+ # unique. You may also wish to constrain it to NOT NULL, but this depends on your
35
+ # app's behavior and requirements.
36
+ #
37
+ ### Example Setup
38
+ #
39
+ # # your model
40
+ # class Post < ActiveRecord::Base
41
+ # extend FriendlyId
42
+ # friendly_id :title, :use => :slugged
43
+ # validates_presence_of :title, :slug, :body
44
+ # end
45
+ #
46
+ # # a migration
47
+ # class CreatePosts < ActiveRecord::Migration
48
+ # def self.up
49
+ # create_table :posts do |t|
50
+ # t.string :title, :null => false
51
+ # t.string :slug, :null => false
52
+ # t.text :body
53
+ # end
54
+ #
55
+ # add_index :posts, :slug, :unique => true
56
+ # end
57
+ #
58
+ # def self.down
59
+ # drop_table :posts
60
+ # end
61
+ # end
62
+ #
63
+ ### Working With Slugs
64
+ #
65
+ #### Formatting
66
+ #
67
+ # By default, FriendlyId uses Active Support's
68
+ # [parameterize](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize)
69
+ # method to create slugs. This method will intelligently replace spaces with
70
+ # dashes, and Unicode Latin characters with ASCII approximations:
71
+ #
72
+ # movie = Movie.create! :title => "Der Preis fürs Überleben"
73
+ # movie.slug #=> "der-preis-furs-uberleben"
74
+ #
75
+ #### Column or Method?
76
+ #
77
+ # FriendlyId always uses a method as the basis of the slug text - not a column. At
78
+ # first glance, this may sound confusing, but remember that Active Record provides
79
+ # methods for each column in a model's associated table, and that's what
80
+ # FriendlyId uses.
81
+ #
82
+ # Here's an example of a class that uses a custom method to generate the slug:
83
+ #
84
+ # class Person < ActiveRecord::Base
85
+ # extend FriendlyId
86
+ # friendly_id :name_and_location, use: :slugged
87
+ #
88
+ # def name_and_location
89
+ # "#{name} from #{location}"
90
+ # end
91
+ # end
92
+ #
93
+ # bob = Person.create! :name => "Bob Smith", :location => "New York City"
94
+ # bob.friendly_id #=> "bob-smith-from-new-york-city"
95
+ #
96
+ # FriendlyId refers to this internally as the "base" method.
97
+ #
98
+ #### Uniqueness
99
+ #
100
+ # When you try to insert a record that would generate a duplicate friendly id,
101
+ # FriendlyId will append a UUID to the generated slug to ensure uniqueness:
102
+ #
103
+ # car = Car.create :title => "Peugeot 206"
104
+ # car2 = Car.create :title => "Peugeot 206"
105
+ #
106
+ # car.friendly_id #=> "peugeot-206"
107
+ # car2.friendly_id #=> "peugeot-206-f9f3789a-daec-4156-af1d-fab81aa16ee5"
108
+ #
109
+ # Previous versions of FriendlyId appended a numeric sequence to make slugs
110
+ # unique, but this was removed to simplify using FriendlyId in concurrent code.
111
+ #
112
+ #### Candidates
113
+ #
114
+ # Since UUIDs are ugly, FriendlyId provides a "slug candidates" functionality to
115
+ # let you specify alternate slugs to use in the event the one you want to use is
116
+ # already taken. For example:
117
+ #
118
+ # class Restaurant < ActiveRecord::Base
119
+ # extend FriendlyId
120
+ # friendly_id :slug_candidates, use: :slugged
121
+ #
122
+ # # Try building a slug based on the following fields in
123
+ # # increasing order of specificity.
124
+ # def slug_candidates
125
+ # [
126
+ # :name,
127
+ # [:name, :city],
128
+ # [:name, :street, :city],
129
+ # [:name, :street_number, :street, :city]
130
+ # ]
131
+ # end
132
+ # end
133
+ #
134
+ # r1 = Restaurant.create! name: 'Plaza Diner', city: 'New Paltz'
135
+ # r2 = Restaurant.create! name: 'Plaza Diner', city: 'Kingston'
136
+ #
137
+ # r1.friendly_id #=> 'plaza-diner'
138
+ # r2.friendly_id #=> 'plaza-diner-kingston'
139
+ #
140
+ # To use candidates, make your FriendlyId base method return an array. The
141
+ # method need not be named `slug_candidates`; it can be anything you want. The
142
+ # array may contain any combination of symbols, strings, procs or lambdas and
143
+ # will be evaluated lazily and in order. If you include symbols, FriendlyId will
144
+ # invoke a method on your model class with the same name. Strings will be
145
+ # interpreted literally. Procs and lambdas will be called and their return values
146
+ # used as the basis of the friendly id. If none of the candidates can generate a
147
+ # unique slug, then FriendlyId will append a UUID to the first candidate as a
148
+ # last resort.
149
+ #
150
+ #### Sequence Separator
151
+ #
152
+ # By default, FriendlyId uses a dash to separate the slug from a sequence.
153
+ #
154
+ # You can change this with the {FriendlyId::Slugged::Configuration#sequence_separator
155
+ # sequence_separator} configuration option.
156
+ #
157
+ #### Providing Your Own Slug Processing Method
158
+ #
159
+ # You can override {FriendlyId::Slugged#normalize_friendly_id} in your model for
160
+ # total control over the slug format. It will be invoked for any generated slug,
161
+ # whether for a single slug or for slug candidates.
162
+ #
163
+ #### Deciding When to Generate New Slugs
164
+ #
165
+ # As of FriendlyId 5.0, slugs are only generated when the `slug` field is nil. If
166
+ # you want a slug to be regenerated,set the slug field to nil:
167
+ #
168
+ # restaurant.friendly_id # joes-diner
169
+ # restaurant.name = "The Plaza Diner"
170
+ # restaurant.save!
171
+ # restaurant.friendly_id # joes-diner
172
+ # restaurant.slug = nil
173
+ # restaurant.save!
174
+ # restaurant.friendly_id # the-plaza-diner
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
188
+ #
189
+ # If you want to extend the default behavior but add your own conditions,
190
+ # don't forget to invoke `super` from your implementation:
191
+ #
192
+ # class Category < ActiveRecord::Base
193
+ # extend FriendlyId
194
+ # friendly_id :name, :use => :slugged
195
+ #
196
+ # def should_generate_new_friendly_id?
197
+ # name_changed? || super
198
+ # end
199
+ # end
200
+ #
201
+ #### Locale-specific Transliterations
202
+ #
203
+ # Active Support's `parameterize` uses
204
+ # [transliterate](http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate),
205
+ # which in turn can use I18n's transliteration rules to consider the current
206
+ # locale when replacing Latin characters:
207
+ #
208
+ # # config/locales/de.yml
209
+ # de:
210
+ # i18n:
211
+ # transliterate:
212
+ # rule:
213
+ # ü: "ue"
214
+ # ö: "oe"
215
+ # etc...
216
+ #
217
+ # movie = Movie.create! :title => "Der Preis fürs Überleben"
218
+ # movie.slug #=> "der-preis-fuers-ueberleben"
219
+ #
220
+ # This functionality was in fact taken from earlier versions of FriendlyId.
221
+ #
222
+ #### Gotchas: Common Problems
223
+ #
224
+ # FriendlyId uses a before_validation callback to generate and set the slug. This
225
+ # means that if you create two model instances before saving them, it's possible
226
+ # they will generate the same slug, and the second save will fail.
227
+ #
228
+ # This can happen in two fairly normal cases: the first, when a model using nested
229
+ # attributes creates more than one record for a model that uses friendly_id. The
230
+ # second, in concurrent code, either in threads or multiple processes.
231
+ #
232
+ # To solve the nested attributes issue, I recommend simply avoiding them when
233
+ # creating more than one nested record for a model that uses FriendlyId. See [this
234
+ # Github issue](https://github.com/norman/friendly_id/issues/185) for discussion.
235
+ #
239
236
  module Slugged
240
-
241
237
  # Sets up behavior and configuration options for FriendlyId's slugging
242
238
  # feature.
243
239
  def self.included(model_class)
244
240
  model_class.friendly_id_config.instance_eval do
245
241
  self.class.send :include, Configuration
246
- self.slug_generator_class ||= SlugGenerator
247
- defaults[:slug_column] ||= 'slug'
248
- defaults[:sequence_separator] ||= '-'
242
+ self.slug_generator_class ||= SlugGenerator
243
+ defaults[:slug_column] ||= "slug"
244
+ defaults[:sequence_separator] ||= "-"
249
245
  end
250
246
  model_class.before_validation :set_slug
251
247
  model_class.before_save :set_slug
@@ -1,3 +1,3 @@
1
1
  module FriendlyId
2
- VERSION = '5.4.2'.freeze
2
+ VERSION = "5.5.0".freeze
3
3
  end
data/lib/friendly_id.rb CHANGED
@@ -1,55 +1,51 @@
1
- # encoding: utf-8
2
- require 'active_record'
1
+ require "active_record"
3
2
  require "friendly_id/base"
4
3
  require "friendly_id/object_utils"
5
4
  require "friendly_id/configuration"
6
5
  require "friendly_id/finder_methods"
7
6
 
8
- =begin
9
-
7
+ #
10
8
  ## About FriendlyId
11
-
12
- FriendlyId is an add-on to Ruby's Active Record that allows you to replace ids
13
- in your URLs with strings:
14
-
15
- # without FriendlyId
16
- http://example.com/states/4323454
17
-
18
- # with FriendlyId
19
- http://example.com/states/washington
20
-
21
- It requires few changes to your application code and offers flexibility,
22
- performance and a well-documented codebase.
23
-
9
+ #
10
+ # FriendlyId is an add-on to Ruby's Active Record that allows you to replace ids
11
+ # in your URLs with strings:
12
+ #
13
+ # # without FriendlyId
14
+ # http://example.com/states/4323454
15
+ #
16
+ # # with FriendlyId
17
+ # http://example.com/states/washington
18
+ #
19
+ # It requires few changes to your application code and offers flexibility,
20
+ # performance and a well-documented codebase.
21
+ #
24
22
  ### Core Concepts
25
-
23
+ #
26
24
  #### Slugs
27
-
28
- The concept of *slugs* is at the heart of FriendlyId.
29
-
30
- A slug is the part of a URL which identifies a page using human-readable
31
- keywords, rather than an opaque identifier such as a numeric id. This can make
32
- your application more friendly both for users and search engines.
33
-
25
+ #
26
+ # The concept of *slugs* is at the heart of FriendlyId.
27
+ #
28
+ # A slug is the part of a URL which identifies a page using human-readable
29
+ # keywords, rather than an opaque identifier such as a numeric id. This can make
30
+ # your application more friendly both for users and search engines.
31
+ #
34
32
  #### Finders: Slugs Act Like Numeric IDs
35
-
36
- To the extent possible, FriendlyId lets you treat text-based identifiers like
37
- normal IDs. This means that you can perform finds with slugs just like you do
38
- with numeric ids:
39
-
40
- Person.find(82542335)
41
- Person.friendly.find("joe")
42
-
43
- =end
33
+ #
34
+ # To the extent possible, FriendlyId lets you treat text-based identifiers like
35
+ # normal IDs. This means that you can perform finds with slugs just like you do
36
+ # with numeric ids:
37
+ #
38
+ # Person.find(82542335)
39
+ # Person.friendly.find("joe")
40
+ #
44
41
  module FriendlyId
45
-
46
- autoload :History, "friendly_id/history"
47
- autoload :Slug, "friendly_id/slug"
48
- autoload :SimpleI18n, "friendly_id/simple_i18n"
49
- autoload :Reserved, "friendly_id/reserved"
50
- autoload :Scoped, "friendly_id/scoped"
51
- autoload :Slugged, "friendly_id/slugged"
52
- autoload :Finders, "friendly_id/finders"
42
+ autoload :History, "friendly_id/history"
43
+ autoload :Slug, "friendly_id/slug"
44
+ autoload :SimpleI18n, "friendly_id/simple_i18n"
45
+ autoload :Reserved, "friendly_id/reserved"
46
+ autoload :Scoped, "friendly_id/scoped"
47
+ autoload :Slugged, "friendly_id/slugged"
48
+ autoload :Finders, "friendly_id/finders"
53
49
  autoload :SequentiallySlugged, "friendly_id/sequentially_slugged"
54
50
 
55
51
  # FriendlyId takes advantage of `extended` to do basic model setup, primarily
@@ -77,7 +73,7 @@ module FriendlyId
77
73
  def self.extended(model_class)
78
74
  return if model_class.respond_to? :friendly_id
79
75
  class << model_class
80
- alias relation_without_friendly_id relation
76
+ alias_method :relation_without_friendly_id, :relation
81
77
  end
82
78
  model_class.class_eval do
83
79
  extend Base
@@ -102,8 +98,8 @@ module FriendlyId
102
98
  # config.use :slugged
103
99
  # end
104
100
  def self.defaults(&block)
105
- @defaults = block if block_given?
106
- @defaults ||= ->(config) {config.use :reserved}
101
+ @defaults = block if block
102
+ @defaults ||= ->(config) { config.use :reserved }
107
103
  end
108
104
 
109
105
  # Set the ActiveRecord table name prefix to friendly_id_