geothird_friendly_id 4.0.9.1

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 (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +12 -0
  4. data/.travis.yml +20 -0
  5. data/.yardopts +4 -0
  6. data/Changelog.md +86 -0
  7. data/Gemfile +15 -0
  8. data/Guide.rdoc +553 -0
  9. data/MIT-LICENSE +19 -0
  10. data/README.md +150 -0
  11. data/Rakefile +108 -0
  12. data/WhatsNew.md +95 -0
  13. data/bench.rb +63 -0
  14. data/friendly_id.gemspec +43 -0
  15. data/gemfiles/Gemfile.rails-3.0.rb +21 -0
  16. data/gemfiles/Gemfile.rails-3.1.rb +22 -0
  17. data/gemfiles/Gemfile.rails-3.2.rb +22 -0
  18. data/geothird_friendly_id.gemspec +43 -0
  19. data/lib/friendly_id/base.rb +291 -0
  20. data/lib/friendly_id/configuration.rb +80 -0
  21. data/lib/friendly_id/finder_methods.rb +35 -0
  22. data/lib/friendly_id/globalize.rb +115 -0
  23. data/lib/friendly_id/history.rb +134 -0
  24. data/lib/friendly_id/migration.rb +18 -0
  25. data/lib/friendly_id/object_utils.rb +50 -0
  26. data/lib/friendly_id/reserved.rb +68 -0
  27. data/lib/friendly_id/scoped.rb +149 -0
  28. data/lib/friendly_id/simple_i18n.rb +95 -0
  29. data/lib/friendly_id/slug.rb +14 -0
  30. data/lib/friendly_id/slug_generator.rb +80 -0
  31. data/lib/friendly_id/slugged.rb +329 -0
  32. data/lib/friendly_id.rb +114 -0
  33. data/lib/generators/friendly_id_generator.rb +17 -0
  34. data/test/base_test.rb +72 -0
  35. data/test/compatibility/ancestry/Gemfile +8 -0
  36. data/test/compatibility/ancestry/ancestry_test.rb +34 -0
  37. data/test/compatibility/threading/Gemfile +8 -0
  38. data/test/compatibility/threading/Gemfile.lock +37 -0
  39. data/test/compatibility/threading/threading.rb +45 -0
  40. data/test/configuration_test.rb +48 -0
  41. data/test/core_test.rb +48 -0
  42. data/test/databases.yml +19 -0
  43. data/test/generator_test.rb +20 -0
  44. data/test/globalize_test.rb +57 -0
  45. data/test/helper.rb +87 -0
  46. data/test/history_test.rb +149 -0
  47. data/test/object_utils_test.rb +28 -0
  48. data/test/reserved_test.rb +40 -0
  49. data/test/schema.rb +79 -0
  50. data/test/scoped_test.rb +83 -0
  51. data/test/shared.rb +156 -0
  52. data/test/simple_i18n_test.rb +133 -0
  53. data/test/slugged_test.rb +280 -0
  54. data/test/sti_test.rb +77 -0
  55. metadata +247 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 878d3503934309a5f33b75fbfcbcd0f39f2c7308
4
+ data.tar.gz: f76a3f30b63f8531225b6f96afa24b5cded31d07
5
+ SHA512:
6
+ metadata.gz: 40e592b60bae27aea119208769c343bb191bab7cbc91fdbca5894f9dcdc7ec02ee6d6510a61334e749fed8d1272fd8a0561b3d459d6610780f03ec700f254f84
7
+ data.tar.gz: baafd016378fc23b5cef06267ad77475d87ca9720dd01268b51ba9b7e7e8d1fd0e7e225161498b4bb1e9fc5fdee7f97c396c6b74fabf71f297a450215a213841
data/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,12 @@
1
+ Gemfile.lock
2
+ doc
3
+ docs
4
+ pkg
5
+ .DS_Store
6
+ coverage
7
+ .yardoc
8
+ *.gem
9
+ *.sqlite3
10
+ *.rbc
11
+ *.lock
12
+ .rbx
data/.travis.yml ADDED
@@ -0,0 +1,20 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 1.8.7
4
+ # - jruby
5
+ # - rbx
6
+
7
+ branches:
8
+ only:
9
+ - master
10
+ env:
11
+ - DB=postgres
12
+ - DB=mysql
13
+ - DB=sqlite3
14
+
15
+ gemfile:
16
+ - gemfiles/Gemfile.rails-3.0.rb
17
+ - gemfiles/Gemfile.rails-3.1.rb
18
+ - gemfiles/Gemfile.rails-3.2.rb
19
+ before_script: 'bundle exec rake db:create db:up > /dev/null'
20
+ script: 'bundle exec rake test'
data/.yardopts ADDED
@@ -0,0 +1,4 @@
1
+ --files=WhatsNew.md,Changelog.md,Guide.rdoc
2
+ --private
3
+ --protected
4
+ --exclude lib/friendly_id/migration
data/Changelog.md ADDED
@@ -0,0 +1,86 @@
1
+ # FriendlyId Changelog
2
+
3
+ We would like to think our many {file:Contributors contributors} for
4
+ suggestions, ideas and improvements to FriendlyId.
5
+
6
+ * Table of Contents
7
+ {:toc}
8
+
9
+ ## 4.0.9 (2012-10-31)
10
+
11
+ * Fixed support for Rails 3.2.9.rc1
12
+
13
+ ## 4.0.8 (2012-08-01)
14
+
15
+ * Name internal anonymous class to fix marshall dump/load error (Jess Brown, Philip Arndt and Norman Clarke).
16
+
17
+ * Avoid using deprecated `update_attribute` (Philip Arndt).
18
+
19
+ * Added set_friendly_id method to Globalize module (Norman Clarke).
20
+
21
+ * autoload FriendlyId::Slug; previously this class was not accessible from
22
+ migrations unless required explicitly, which could cause some queries to
23
+ unexpectedly fail (Norman Clarke).
24
+
25
+ * Fix Mocha load order (Mark Turner).
26
+
27
+ * Minor doc updates (Rob Yurkowski).
28
+
29
+ * Other miscellaneous refactorings and doc updates.
30
+
31
+ ## 4.0.7 (2012-06-06)
32
+
33
+ * to_param just calls super when no friendly_id is present, to keep the model's
34
+ default behavior. (Andrew White)
35
+
36
+ * FriendlyId can now properly sequence slugs that end in numbers even when a
37
+ single dash is used as the separator (Tomás Arribas).
38
+
39
+ ## 4.0.6 (2012-05-21)
40
+
41
+ * Fix nil return value from to_param when save fails because of validation errors (Tomás Arribas)
42
+ * Fix incorrect usage of i18n API (Vinicius Ferriani)
43
+ * Improve error handling in reserved module (Adrián Mugnolo and Github user "nolamesa")
44
+
45
+ ## 4.0.5 (2012-04-28)
46
+
47
+ * Favor `includes` over `joins` in globalize to avoid read-only results (Jakub Wojtysiak)
48
+ * Fix globalize compatibility with results from dynamic finders (Chris Salzberg)
49
+
50
+
51
+ ## 4.0.4 (2012-03-26)
52
+
53
+ * Fix globalize plugin to avoid issues with asset precompilation (Philip Arndt)
54
+
55
+
56
+ ## 4.0.3 (2012-03-14)
57
+
58
+ * Fix escape for '%' and '_' on SQLite (Norman Clarke and Sergey Petrunin)
59
+ * Allow FriendlyId to be extended or included (Norman Clarke)
60
+ * Allow Configuration#use to accept a Module (Norman Clarke)
61
+ * Fix bugs with History module + STI (Norman Clarke and Sergey Petrunin)
62
+
63
+ ## 4.0.2 (2012-03-12)
64
+
65
+ * Improved conflict handling and performance in History module (Erik Ogan and Thomas Shafer)
66
+ * Fixed bug that impeded using underscores as a sequence separator (Erik Ogan and Thomas Shafer)
67
+ * Minor documentation improvements (Norman Clarke)
68
+
69
+ ## 4.0.1 (2012-02-29)
70
+
71
+ * Added support for Globalize 3 (Enrico Pilotto and Philip Arndt)
72
+ * Allow the scoped module to use multiple scopes (Ben Caldwell)
73
+ * Fixes for conflicting slugs in history module (Erik Ogan, Thomas Shafer, Evan Arnold)
74
+ * Fix for conflicting slugs when using STI (Danny van der Heiden, Diederick Lawson)
75
+ * Maintainence improvements (Norman Clarke, Philip Arndt, Thomas Darde, Lee Hambley)
76
+
77
+ ## 4.0.0 (2011-12-27)
78
+
79
+ This is a complete rewrite of FriendlyId, and introduces a smaller, faster and
80
+ less ambitious codebase. The primary change is the relegation of external slugs
81
+ to an optional addon, and the adoption of what were formerly "cached slugs"
82
+ as the primary way of handling slugging.
83
+
84
+ ## Older releases
85
+
86
+ Please see the 3.x branch.
data/Gemfile ADDED
@@ -0,0 +1,15 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ # Database Configuration
6
+ group :development, :test do
7
+ platforms :jruby do
8
+ gem 'activerecord-jdbcsqlite3-adapter'
9
+ gem 'jruby-openssl'
10
+ end
11
+
12
+ platforms :ruby do
13
+ gem 'sqlite3'
14
+ end
15
+ end
data/Guide.rdoc ADDED
@@ -0,0 +1,553 @@
1
+ #encoding: utf-8
2
+
3
+
4
+ == About FriendlyId
5
+
6
+ FriendlyId is an add-on to Ruby's Active Record that allows you to replace ids
7
+ in your URLs with strings:
8
+
9
+ # without FriendlyId
10
+ http://example.com/states/4323454
11
+
12
+ # with FriendlyId
13
+ http://example.com/states/washington
14
+
15
+ It requires few changes to your application code and offers flexibility,
16
+ performance and a well-documented codebase.
17
+
18
+ === Core Concepts
19
+
20
+ ==== Slugs
21
+
22
+ The concept of "slugs[http://en.wikipedia.org/wiki/Slug_(web_publishing)]" is at
23
+ the heart of FriendlyId.
24
+
25
+ A slug is the part of a URL which identifies a page using human-readable
26
+ keywords, rather than an opaque identifier such as a numeric id. This can make
27
+ your application more friendly both for users and search engine.
28
+
29
+ ==== Finders: Slugs Act Like Numeric IDs
30
+
31
+ To the extent possible, FriendlyId lets you treat text-based identifiers like
32
+ normal IDs. This means that you can perform finds with slugs just like you do
33
+ with numeric ids:
34
+
35
+ Person.find(82542335)
36
+ Person.find("joe")
37
+
38
+
39
+ == Setting Up FriendlyId in Your Model
40
+
41
+ To use FriendlyId in your ActiveRecord models, you must first either extend or
42
+ include the FriendlyId module (it makes no difference), then invoke the
43
+ {FriendlyId::Base#friendly_id friendly_id} method to configure your desired
44
+ options:
45
+
46
+ class Foo < ActiveRecord::Base
47
+ include FriendlyId
48
+ friendly_id :bar, :use => [:slugged, :simple_i18n]
49
+ end
50
+
51
+ The most important option is `:use`, which you use to tell FriendlyId which
52
+ addons it should use. See the documentation for this method for a list of all
53
+ available addons, or skim through the rest of the docs to get a high-level
54
+ overview.
55
+
56
+ === The Default Setup: Simple Models
57
+
58
+ The simplest way to use FriendlyId is with a model that has a uniquely indexed
59
+ column with no spaces or special characters, and that is seldom or never
60
+ updated. The most common example of this is a user name:
61
+
62
+ class User < ActiveRecord::Base
63
+ extend FriendlyId
64
+ friendly_id :login
65
+ validates_format_of :login, :with => /\A[a-z0-9]+\z/i
66
+ end
67
+
68
+ @user = User.find "joe" # the old User.find(1) still works, too
69
+ @user.to_param # returns "joe"
70
+ redirect_to @user # the URL will be /users/joe
71
+
72
+ In this case, FriendlyId assumes you want to use the column as-is; it will never
73
+ modify the value of the column, and your application should ensure that the
74
+ value is unique and admissible in a URL:
75
+
76
+ class City < ActiveRecord::Base
77
+ extend FriendlyId
78
+ friendly_id :name
79
+ end
80
+
81
+ @city.find "Viña del Mar"
82
+ redirect_to @city # the URL will be /cities/Viña%20del%20Mar
83
+
84
+ Writing the code to process an arbitrary string into a good identifier for use
85
+ in a URL can be repetitive and surprisingly tricky, so for this reason it's
86
+ often better and easier to use {FriendlyId::Slugged slugs}.
87
+
88
+
89
+ == Slugged Models
90
+
91
+ FriendlyId can use a separate column to store slugs for models which require
92
+ some text processing.
93
+
94
+ For example, blog applications typically use a post title to provide the basis
95
+ of a search engine friendly URL. Such identifiers typically lack uppercase
96
+ characters, use ASCII to approximate UTF-8 character, and strip out other
97
+ characters which may make them aesthetically unappealing or error-prone when
98
+ used in a URL.
99
+
100
+ class Post < ActiveRecord::Base
101
+ extend FriendlyId
102
+ friendly_id :title, :use => :slugged
103
+ end
104
+
105
+ @post = Post.create(:title => "This is the first post!")
106
+ @post.friendly_id # returns "this-is-the-first-post"
107
+ redirect_to @post # the URL will be /posts/this-is-the-first-post
108
+
109
+ In general, use slugs by default unless you know for sure you don't need them.
110
+ To activate the slugging functionality, use the {FriendlyId::Slugged} module.
111
+
112
+ FriendlyId will generate slugs from a method or column that you specify, and
113
+ store them in a field in your model. By default, this field must be named
114
+ +:slug+, though you may change this using the
115
+ {FriendlyId::Slugged::Configuration#slug_column slug_column} configuration
116
+ option. You should add an index to this column, and in most cases, make it
117
+ unique. Do not make the column unique in case you wish to scope the slug
118
+ (more on this later). You may also wish to constrain it to NOT NULL, but this
119
+ depends on your app's behavior and requirements.
120
+
121
+ === Example Setup
122
+
123
+ # your model
124
+ class Post < ActiveRecord::Base
125
+ extend FriendlyId
126
+ friendly_id :title, :use => :slugged
127
+ validates_presence_of :title, :slug, :body
128
+ end
129
+
130
+ # a migration
131
+ class CreatePosts < ActiveRecord::Migration
132
+ def self.up
133
+ create_table :posts do |t|
134
+ t.string :title, :null => false
135
+ t.string :slug, :null => false
136
+ t.text :body
137
+ end
138
+
139
+ add_index :posts, :slug, :unique => true
140
+ end
141
+
142
+ def self.down
143
+ drop_table :posts
144
+ end
145
+ end
146
+
147
+ === Working With Slugs
148
+
149
+ ==== Formatting
150
+
151
+ By default, FriendlyId uses Active Support's
152
+ paramaterize[http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize]
153
+ method to create slugs. This method will intelligently replace spaces with
154
+ dashes, and Unicode Latin characters with ASCII approximations:
155
+
156
+ movie = Movie.create! :title => "Der Preis fürs Überleben"
157
+ movie.slug #=> "der-preis-furs-uberleben"
158
+
159
+ ==== Uniqueness
160
+
161
+ When you try to insert a record that would generate a duplicate friendly id,
162
+ FriendlyId will append a sequence to the generated slug to ensure uniqueness:
163
+
164
+ car = Car.create :title => "Peugot 206"
165
+ car2 = Car.create :title => "Peugot 206"
166
+
167
+ car.friendly_id #=> "peugot-206"
168
+ car2.friendly_id #=> "peugot-206--2"
169
+
170
+ ==== Sequence Separator - The Two Dashes
171
+
172
+ By default, FriendlyId uses two dashes to separate the slug from a sequence.
173
+
174
+ You can change this with the {FriendlyId::Slugged::Configuration#sequence_separator
175
+ sequence_separator} configuration option.
176
+
177
+ ==== Column or Method?
178
+
179
+ FriendlyId always uses a method as the basis of the slug text - not a column. It
180
+ first glance, this may sound confusing, but remember that Active Record provides
181
+ methods for each column in a model's associated table, and that's what
182
+ FriendlyId uses.
183
+
184
+ Here's an example of a class that uses a custom method to generate the slug:
185
+
186
+ class Person < ActiveRecord::Base
187
+ friendly_id :name_and_location
188
+ def name_and_location
189
+ "#{name} from #{location}"
190
+ end
191
+ end
192
+
193
+ bob = Person.create! :name => "Bob Smith", :location => "New York City"
194
+ bob.friendly_id #=> "bob-smith-from-new-york-city"
195
+
196
+ ==== Providing Your Own Slug Processing Method
197
+
198
+ You can override {FriendlyId::Slugged#normalize_friendly_id} in your model for
199
+ total control over the slug format.
200
+
201
+ ==== Deciding When to Generate New Slugs
202
+
203
+ Overriding {FriendlyId::Slugged#should_generate_new_friendly_id?} lets you
204
+ control whether new friendly ids are created when a model is updated. For
205
+ example, if you only want to generate slugs once and then treat them as
206
+ read-only:
207
+
208
+ class Post < ActiveRecord::Base
209
+ extend FriendlyId
210
+ friendly_id :title, :use => :slugged
211
+
212
+ def should_generate_new_friendly_id?
213
+ new_record?
214
+ end
215
+ end
216
+
217
+ post = Post.create!(:title => "Hello world!")
218
+ post.slug #=> "hello-world"
219
+ post.title = "Hello there, world!"
220
+ post.save!
221
+ post.slug #=> "hello-world"
222
+
223
+ ==== Locale-specific Transliterations
224
+
225
+ Active Support's +parameterize+ uses
226
+ transliterate[http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-transliterate],
227
+ which in turn can use I18n's transliteration rules to consider the current
228
+ locale when replacing Latin characters:
229
+
230
+ # config/locales/de.yml
231
+ de:
232
+ i18n:
233
+ transliterate:
234
+ rule:
235
+ ü: "ue"
236
+ ö: "oe"
237
+ etc...
238
+
239
+ movie = Movie.create! :title => "Der Preis fürs Überleben"
240
+ movie.slug #=> "der-preis-fuers-ueberleben"
241
+
242
+ This functionality was in fact taken from earlier versions of FriendlyId.
243
+
244
+ ==== Gotchas: Common Problems
245
+
246
+ ===== Slugs That Begin With Numbers
247
+
248
+ Ruby's `to_i` function casts strings to integers in such a way that +23abc.to_i+
249
+ returns 23. Because FriendlyId falls back to finding by numeric id, this means
250
+ that if you attempt to find a record with a non-existant slug, and that slug
251
+ begins with a number, your find will probably return the wrong record.
252
+
253
+ There are two fairly simple ways to avoid this:
254
+
255
+ * Use validations to ensure that slugs don't begin with numbers.
256
+ * Use explicit finders like +find_by_id+ to always find by the numeric id, or
257
+ +find_by_slug+ to always find using the friendly id.
258
+
259
+ ===== Concurrency Issues
260
+
261
+ FriendlyId uses a before_validation callback to generate and set the slug. This
262
+ means that if you create two model instances before saving them, it's possible
263
+ they will generate the same slug, and the second save will fail.
264
+
265
+ This can happen in two fairly normal cases: the first, when a model using nested
266
+ attributes creates more than one record for a model that uses friendly_id. The
267
+ second, in concurrent code, either in threads or multiple processes.
268
+
269
+ To solve the nested attributes issue, I recommend simply avoiding them when
270
+ creating more than one nested record for a model that uses FriendlyId. See {this
271
+ Github issue}[https://github.com/norman/friendly_id/issues/185] for discussion.
272
+
273
+ To solve the concurrency issue, I recommend locking the model's table against
274
+ inserts while when saving the record. See {this Github
275
+ issue}[https://github.com/norman/friendly_id/issues/180] for discussion.
276
+
277
+
278
+ == History: Avoiding 404's When Slugs Change
279
+
280
+ FriendlyId's {FriendlyId::History History} module adds the ability to store a
281
+ log of a model's slugs, so that when its friendly id changes, it's still
282
+ possible to perform finds by the old id.
283
+
284
+ The primary use case for this is avoiding broken URLs.
285
+
286
+ === Setup
287
+
288
+ In order to use this module, you must add a table to your database schema to
289
+ store the slug records. FriendlyId provides a generator for this purpose:
290
+
291
+ rails generate friendly_id
292
+ rake db:migrate
293
+
294
+ This will add a table named +friendly_id_slugs+, used by the {FriendlyId::Slug}
295
+ model.
296
+
297
+ === Considerations
298
+
299
+ This module is incompatible with the +:scoped+ module.
300
+
301
+ Because recording slug history requires creating additional database records,
302
+ this module has an impact on the performance of the associated model's +create+
303
+ method.
304
+
305
+ === Example
306
+
307
+ class Post < ActiveRecord::Base
308
+ extend FriendlyId
309
+ friendly_id :title, :use => :history
310
+ end
311
+
312
+ class PostsController < ApplicationController
313
+
314
+ before_filter :find_post
315
+
316
+ ...
317
+
318
+ def find_post
319
+ @post = Post.find params[:id]
320
+
321
+ # If an old id or a numeric id was used to find the record, then
322
+ # the request path will not match the post_path, and we should do
323
+ # a 301 redirect that uses the current friendly id.
324
+ if request.path != post_path(@post)
325
+ return redirect_to @post, :status => :moved_permanently
326
+ end
327
+ end
328
+ end
329
+
330
+
331
+ == Unique Slugs by Scope
332
+
333
+ The {FriendlyId::Scoped} module allows FriendlyId to generate unique slugs
334
+ within a scope.
335
+
336
+ This allows, for example, two restaurants in different cities to have the slug
337
+ +joes-diner+:
338
+
339
+ class Restaurant < ActiveRecord::Base
340
+ extend FriendlyId
341
+ belongs_to :city
342
+ friendly_id :name, :use => :scoped, :scope => :city
343
+ end
344
+
345
+ class City < ActiveRecord::Base
346
+ extend FriendlyId
347
+ has_many :restaurants
348
+ friendly_id :name, :use => :slugged
349
+ end
350
+
351
+ City.find("seattle").restaurants.find("joes-diner")
352
+ City.find("chicago").restaurants.find("joes-diner")
353
+
354
+ Without :scoped in this case, one of the restaurants would have the slug
355
+ +joes-diner+ and the other would have +joes-diner--2+.
356
+
357
+ The value for the +:scope+ option can be the name of a +belongs_to+ relation, or
358
+ a column.
359
+
360
+ Please do note that you must drop the uniqueness constraint on the slug's
361
+ column in the database when you're scoping the slug.
362
+
363
+ === Finding Records by Friendly ID
364
+
365
+ If you are using scopes your friendly ids may not be unique, so a simple find
366
+ like
367
+
368
+ Restaurant.find("joes-diner")
369
+
370
+ may return the wrong record. In these cases it's best to query through the
371
+ relation:
372
+
373
+ @city.restaurants.find("joes-diner")
374
+
375
+ Alternatively, you could pass the scope value as a query parameter:
376
+
377
+ Restaurant.find("joes-diner").where(:city_id => @city.id)
378
+
379
+
380
+ === Finding All Records That Match a Scoped ID
381
+
382
+ Query the slug column directly:
383
+
384
+ Restaurant.find_all_by_slug("joes-diner")
385
+
386
+ === Routes for Scoped Models
387
+
388
+ Recall that FriendlyId is a database-centric library, and does not set up any
389
+ routes for scoped models. You must do this yourself in your application. Here's
390
+ an example of one way to set this up:
391
+
392
+ # in routes.rb
393
+ resources :cities do
394
+ resources :restaurants
395
+ end
396
+
397
+ # in views
398
+ <%= link_to 'Show', [@city, @restaurant] %>
399
+
400
+ # in controllers
401
+ @city = City.find(params[:city_id])
402
+ @restaurant = @city.restaurants.find(params[:id])
403
+
404
+ # URLs:
405
+ http://example.org/cities/seattle/restaurants/joes-diner
406
+ http://example.org/cities/chicago/restaurants/joes-diner
407
+
408
+
409
+ == Translating Slugs Using Simple I18n
410
+
411
+ The {FriendlyId::SimpleI18n SimpleI18n} module adds very basic i18n support to
412
+ FriendlyId.
413
+
414
+ In order to use this module, your model must have a slug column for each locale.
415
+ By default FriendlyId looks for columns named, for example, "slug_en",
416
+ "slug_es", etc. The first part of the name can be configured by passing the
417
+ +:slug_column+ option if you choose. Note that the column for the default locale
418
+ must also include the locale in its name.
419
+
420
+ This module is most suitable to applications that need to support few locales.
421
+ If you need to support two or more locales, you may wish to use the
422
+ {FriendlyId::Globalize Globalize} module instead.
423
+
424
+ === Example migration
425
+
426
+ def self.up
427
+ create_table :posts do |t|
428
+ t.string :title
429
+ t.string :slug_en
430
+ t.string :slug_es
431
+ t.text :body
432
+ end
433
+ add_index :posts, :slug_en
434
+ add_index :posts, :slug_es
435
+ end
436
+
437
+ === Finds
438
+
439
+ Finds will take into consideration the current locale:
440
+
441
+ I18n.locale = :es
442
+ Post.find("la-guerra-de-las-galaxas")
443
+ I18n.locale = :en
444
+ Post.find("star-wars")
445
+
446
+ To find a slug by an explicit locale, perform the find inside a block
447
+ passed to I18n's +with_locale+ method:
448
+
449
+ I18n.with_locale(:es) do
450
+ Post.find("la-guerra-de-las-galaxas")
451
+ end
452
+
453
+ === Creating Records
454
+
455
+ When new records are created, the slug is generated for the current locale only.
456
+
457
+ === Translating Slugs
458
+
459
+ To translate an existing record's friendly_id, use
460
+ {FriendlyId::SimpleI18n::Model#set_friendly_id}. This will ensure that the slug
461
+ you add is properly escaped, transliterated and sequenced:
462
+
463
+ post = Post.create :name => "Star Wars"
464
+ post.set_friendly_id("La guerra de las galaxas", :es)
465
+
466
+ If you don't pass in a locale argument, FriendlyId::SimpleI18n will just use the
467
+ current locale:
468
+
469
+ I18n.with_locale(:es) do
470
+ post.set_friendly_id("la-guerra-de-las-galaxas")
471
+ end
472
+
473
+
474
+ == Translating Slugs Using Globalize
475
+
476
+ The {FriendlyId::Globalize Globalize} module lets you use
477
+ Globalize[https://github.com/svenfuchs/globalize3] to translate slugs. This
478
+ module is most suitable for applications that need to be localized to many
479
+ languages. If your application only needs to be localized to one or two
480
+ languages, you may wish to consider the {FriendlyId::SimpleI18n SimpleI18n}
481
+ module.
482
+
483
+ In order to use this module, your model's table and translation table must both
484
+ have a slug column, and your model must set the +slug+ field as translatable
485
+ with Globalize:
486
+
487
+ class Post < ActiveRecord::Base
488
+ translates :title, :slug
489
+ extend FriendlyId
490
+ friendly_id :title, :use => :globalize
491
+ end
492
+
493
+ === Finds
494
+
495
+ Finds will take the current locale into consideration:
496
+
497
+ I18n.locale = :it
498
+ Post.find("guerre-stellari")
499
+ I18n.locale = :en
500
+ Post.find("star-wars")
501
+
502
+ To find a slug by an explicit locale, perform the find inside a block
503
+ passed to I18n's +with_locale+ method:
504
+
505
+ I18n.with_locale(:it) do
506
+ Post.find("guerre-stellari")
507
+ end
508
+
509
+ === Creating Records
510
+
511
+ When new records are created, the slug is generated for the current locale only.
512
+
513
+ === Translating Slugs
514
+
515
+ To translate an existing record's friendly_id, simply change the locale and
516
+ assign a value to the +slug+ field:
517
+
518
+ I18n.with_locale(:it) do
519
+ post.slug = "guerre-stellari"
520
+ end
521
+
522
+
523
+ == Reserved Words
524
+
525
+ The {FriendlyId::Reserved Reserved} module adds the ability to exlude a list of
526
+ words from use as FriendlyId slugs.
527
+
528
+ By default, FriendlyId reserves the words "new" and "edit" when this module is
529
+ included. You can configure this globally by using {FriendlyId.defaults
530
+ FriendlyId.defaults}:
531
+
532
+ FriendlyId.defaults do |config|
533
+ config.use :reserved
534
+ # Reserve words for English and Spanish URLs
535
+ config.reserved_words = %w(new edit nueva nuevo editar)
536
+ end
537
+
538
+ Note that the error message will appear on the field +:friendly_id+. If you are
539
+ using Rails's scaffolded form errors display, then it will have no field to
540
+ highlight. If you'd like to change this so that scaffolding works as expected,
541
+ one way to accomplish this is to move the error message to a different field.
542
+ For example:
543
+
544
+ class Person < ActiveRecord::Base
545
+ extend FriendlyId
546
+ friendly_id :name, use: :slugged
547
+
548
+ after_validation :move_friendly_id_error_to_name
549
+
550
+ def move_friendly_id_error_to_name
551
+ errors.messages[:name] = errors.messages.delete(:friendly_id)
552
+ end
553
+ end