friendly_id4 4.0.0.beta4 → 4.0.0.beta5

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: friendly_id4
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0.beta4
4
+ version: 4.0.0.beta5
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,12 +9,12 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-07-29 00:00:00.000000000 -03:00
12
+ date: 2011-08-06 00:00:00.000000000 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
17
- requirement: &70126503605200 !ruby/object:Gem::Requirement
17
+ requirement: &70359454075760 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: '3.0'
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *70126503605200
25
+ version_requirements: *70359454075760
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: sqlite3
28
- requirement: &70126503604500 !ruby/object:Gem::Requirement
28
+ requirement: &70359454075180 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: '1.3'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *70126503604500
36
+ version_requirements: *70359454075180
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: cutest
39
- requirement: &70126503603900 !ruby/object:Gem::Requirement
39
+ requirement: &70359454074720 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,10 +44,10 @@ dependencies:
44
44
  version: 1.1.2
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *70126503603900
47
+ version_requirements: *70359454074720
48
48
  - !ruby/object:Gem::Dependency
49
49
  name: ffaker
50
- requirement: &70126503603440 !ruby/object:Gem::Requirement
50
+ requirement: &70359454074320 !ruby/object:Gem::Requirement
51
51
  none: false
52
52
  requirements:
53
53
  - - ! '>='
@@ -55,10 +55,10 @@ dependencies:
55
55
  version: '0'
56
56
  type: :development
57
57
  prerelease: false
58
- version_requirements: *70126503603440
58
+ version_requirements: *70359454074320
59
59
  - !ruby/object:Gem::Dependency
60
60
  name: maruku
61
- requirement: &70126503602760 !ruby/object:Gem::Requirement
61
+ requirement: &70359454073860 !ruby/object:Gem::Requirement
62
62
  none: false
63
63
  requirements:
64
64
  - - ! '>='
@@ -66,10 +66,10 @@ dependencies:
66
66
  version: '0'
67
67
  type: :development
68
68
  prerelease: false
69
- version_requirements: *70126503602760
69
+ version_requirements: *70359454073860
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: yard
72
- requirement: &70126503602100 !ruby/object:Gem::Requirement
72
+ requirement: &70359454073420 !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
75
  - - ! '>='
@@ -77,10 +77,10 @@ dependencies:
77
77
  version: '0'
78
78
  type: :development
79
79
  prerelease: false
80
- version_requirements: *70126503602100
80
+ version_requirements: *70359454073420
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: mocha
83
- requirement: &70126503601460 !ruby/object:Gem::Requirement
83
+ requirement: &70359454072980 !ruby/object:Gem::Requirement
84
84
  none: false
85
85
  requirements:
86
86
  - - ! '>='
@@ -88,7 +88,7 @@ dependencies:
88
88
  version: '0'
89
89
  type: :development
90
90
  prerelease: false
91
- version_requirements: *70126503601460
91
+ version_requirements: *70359454072980
92
92
  description: ! " FriendlyId is the \"Swiss Army bulldozer\" of slugging and permalink
93
93
  plugins\n for Ruby on Rails. It allows you to create pretty URL's and work with\n
94
94
  \ human-friendly strings as if they were numeric ids for ActiveRecord models.\n"
@@ -100,8 +100,8 @@ extra_rdoc_files: []
100
100
  files:
101
101
  - .gemtest
102
102
  - .gitignore
103
+ - .yardopts
103
104
  - Gemfile
104
- - Guide.md
105
105
  - README.md
106
106
  - Rakefile
107
107
  - WhatsNew.md
@@ -115,11 +115,11 @@ files:
115
115
  - lib/friendly_id/migration.rb
116
116
  - lib/friendly_id/model.rb
117
117
  - lib/friendly_id/object_utils.rb
118
+ - lib/friendly_id/reserved.rb
118
119
  - lib/friendly_id/scoped.rb
119
120
  - lib/friendly_id/slug.rb
120
121
  - lib/friendly_id/slug_sequencer.rb
121
122
  - lib/friendly_id/slugged.rb
122
- - lib/friendly_id/version.rb
123
123
  - lib/generators/friendly_id_generator.rb
124
124
  - test/base_test.rb
125
125
  - test/config/mysql.yml
@@ -130,6 +130,7 @@ files:
130
130
  - test/helper.rb
131
131
  - test/history_test.rb
132
132
  - test/object_utils_test.rb
133
+ - test/reserved_test.rb
133
134
  - test/schema.rb
134
135
  - test/scoped_test.rb
135
136
  - test/shared.rb
data/Guide.md DELETED
@@ -1,363 +0,0 @@
1
- # FriendlyId Guide
2
-
3
- * Table of Contents
4
- {:toc}
5
-
6
- ## Overview
7
-
8
- FriendlyId is an ORM-centric Ruby library that lets you work with human-friendly
9
- strings as if they were numeric ids. Among other things, this facilitates
10
- replacing "unfriendly" URL's like:
11
-
12
- http://example.com/states/4323454
13
-
14
- with "friendly" ones such as:
15
-
16
- http://example.com/states/washington
17
-
18
- FriendlyId is typically used with Rails and Active Record, but can also be used in
19
- non-Rails applications.
20
-
21
- ## Simple Models
22
-
23
- The simplest way to use FriendlyId is with a model that has a uniquely indexed
24
- column with no spaces or special characters, and that is seldom or never
25
- updated. The most common example of this is a user name or login column:
26
-
27
- class User < ActiveRecord::Base
28
- extend FriendlyId
29
- validates_format_of :login, :with => /\A[a-z0-9]+\z/i
30
- friendly_id :login
31
- end
32
-
33
- @user = User.find "joe" # the old User.find(1) still works, too
34
- @user.to_param # returns "joe"
35
- redirect_to @user # the URL will be /users/joe
36
-
37
- In this case, FriendlyId assumes you want to use the column as-is; it will never
38
- modify the value of the column, and your application should ensure that the value
39
- is admissible in a URL:
40
-
41
- class City < ActiveRecord::Base
42
- extend FriendlyId
43
- friendly_id :name
44
- end
45
-
46
- @city.find "Viña del Mar"
47
- redirect_to @city # the URL will be /cities/Viña%20del%20Mar
48
-
49
- For this reason, it is often more convenient to use Slugs rather than a single
50
- column.
51
-
52
- ## Slugged Models
53
-
54
- FriendlyId uses a separate column to store slugs for models which require some
55
- processing of the friendly_id text. The most common example is a blog post's
56
- title, which may have spaces, uppercase characters, or other attributes you
57
- wish to modify to make them more suitable for use in URL's.
58
-
59
- class Post < ActiveRecord::Base
60
- extend FriendlyId
61
- friendly_id :title, :use => :slugged
62
- end
63
-
64
- @post = Post.create(:title => "This is the first post!")
65
- @post.friendly_id # returns "this-is-the-first-post"
66
- redirect_to @post # the URL will be /posts/this-is-the-first-post
67
-
68
- If you are unsure whether to use slugs, then your best bet is to use them,
69
- because FriendlyId provides many useful features that only work with this
70
- feature. These features are explained in detail {file:Guide.md#features below}.
71
-
72
- ## Installation
73
-
74
- gem install friendly_id
75
-
76
- After installing the gem, add an entry in the Gemfile:
77
-
78
- gem "friendly_id", "~> 4.0.0"
79
-
80
- ### Future Compatibility
81
-
82
- FriendlyId will always remain compatible with the current release of Rails, and
83
- at least one stable release behind. That means that support for 3.0.x will not be
84
- dropped until a stable release of 3.2 is out, or possibly longer.
85
-
86
- ## Configuration
87
-
88
- FriendlyId is configured in your model using the `friendly_id` method. Additional
89
- features can be passing the names of modules into the `:use` option:
90
-
91
- class Post < ActiveRecord::Base
92
- extend FriendlyId
93
- # use the "title" accessor as the basis of the friendly_id
94
- friendly_id :title, :use => [:slugged, :history]
95
- end
96
-
97
- Read on to learn about the various features that can be configured. For the
98
- full list of valid configuration options, see the instance attribute summary
99
- for {FriendlyId::Configuration}.
100
-
101
- # Features
102
-
103
- ## FriendlyId Strings
104
-
105
- By default, FriendlyId uses Active Support's Transliterator class to convert strings into
106
- ASCII slugs by default. Please see the API docs for
107
- [transliterate](http://api.rubyonrails.org/) and
108
- [parameterize](http://api.rubyonrails.org/) to see what options are avaialable
109
- to you.
110
-
111
- Previous versions of FriendlyId used [Babosa](github.com/norman/babosa) for slug
112
- string handling, but the core functionality it provides was extracted from it
113
- and added to Rails 3. However, Babosa offers some advanced functionality not
114
- offered by Rails and can still be a convenient option. This section shows how
115
- you can use it with FriendlyId.
116
-
117
- ### Using a Custom Method to Generate the Slug Text
118
-
119
- FriendlyId can use either a column or a method to generate the slug text for
120
- your model:
121
-
122
- class City < ActiveRecord::Base
123
- extend FriendlyId
124
- belongs_to :country
125
- friendly_id :name_and_country, :use => :slugged
126
-
127
- def name_and_country
128
- #{name} #{country.name}
129
- end
130
-
131
- end
132
-
133
- @country = Country.create(:name => "Argentina")
134
- @city = City.create(:name => "Buenos Aires", :country => @country)
135
- @city.friendly_id # will be "buenos-aires-argentina"
136
-
137
- One word of caution: in the example above, if the country's name were updated,
138
- say, to "Argentine Republic", the city's friendly_id would not be
139
- automatically updated. For this reason, it's a good idea to avoid using
140
- frequently-updated relations as a part of the friendly_id.
141
-
142
- ## Using a Custom Method to Process the Slug Text
143
-
144
- If the built-in slug text handling options don't work for your application,
145
- you can override the `normalize_friendly_id` method in your model class in
146
- order to fine-tune the output:
147
-
148
- class City < ActiveRecord::Base
149
- extend FriendlyId
150
- friendly_id :whatever, :use => :slugged
151
-
152
- def normalize_friendly_id(text)
153
- my_text_modifier_method(text)
154
- end
155
-
156
- end
157
-
158
- The `normalize_friendly_id` method takes a single argument and receives an
159
- instance of {FriendlyId::SlugString}, a class which wraps a regular Ruby string
160
- with additional formatting options.
161
-
162
- ### Converting non-Latin characters to ASCII with Babosa
163
-
164
- Babosa offers the ability to idiomatically transliterate non-ASCII characters
165
- to ASCII:
166
-
167
- "Jürgen".to_slug.normalize! #=> "Jurgen"
168
- "Jürgen".to_slug.normalize! :transliterate => :german #=> "Juergen"
169
-
170
- Using Babosa with FriendlyId is a simple matter of installing and requiring
171
- the `babosa` gem, and overriding the `normalize_friendly_id` method in your
172
- model:
173
-
174
- class City < ActiveRecord::Base
175
- def normalize_friendly_id(text)
176
- text.slug.normalize!
177
- end
178
- end
179
-
180
- ## Redirecting to the Current Friendly URL
181
-
182
- FriendlyId can maintain a history of your record's older slugs, so if your
183
- record's friendly_id changes, your URL's won't break.
184
-
185
- class Post < ActiveRecord::Base
186
- extend FriendlyId
187
- friendly_id :title, :use => :history
188
- end
189
-
190
- class PostsController < ApplicationController
191
-
192
- before_filter :find_post
193
-
194
- ...
195
- def find_post
196
- return unless params[:id]
197
- @post = begin
198
- Post.find params[:id]
199
- rescue ActiveRecord::RecordNotFound
200
- Post.find_by_friendly_id params[:id]
201
- end
202
- # If an old id or a numeric id was used to find the record, then
203
- # the request path will not match the post_path, and we should do
204
- # a 301 redirect that uses the current friendly_id
205
- if request.path != post_path(@post)
206
- return redirect_to @post, :status => :moved_permanently
207
- end
208
- end
209
- end
210
-
211
- ## Non-unique Slugs
212
-
213
- FriendlyId will append a arbitrary number to the end of the id to keep it
214
- unique if necessary:
215
-
216
- /posts/new-version-released
217
- /posts/new-version-released--2
218
- /posts/new-version-released--3
219
- ...
220
- etc.
221
-
222
- Note that the number is preceded by "--" rather than "-" to distinguish it from
223
- the rest of the slug. This is important to enable having slugs like:
224
-
225
- /cars/peugeot-206
226
- /cars/peugeot-206--2
227
-
228
- You can configure the separator string used by your model by setting the
229
- `:sequence_separator` option in `friendly_id`:
230
-
231
- friendly_id :title, :use => :slugged, :sequence_separator => ":"
232
-
233
- You can also override the default used in
234
- {FriendlyId::Configuration::DEFAULTS} to set the value for any model using
235
- FriendlyId. If you change this value in an existing application, be sure to
236
- {file:Guide.md#regenerating_slugs regenerate the slugs} afterwards.
237
-
238
- For reasons I hope are obvious, you can't change this value to "-". If you try,
239
- FriendlyId will raise an error.
240
-
241
- ## Reserved Words
242
-
243
- When you use slugs, FriendlyId adds a validation to avoid using "new" and
244
- "index" as slugs. You can control the default reserved words by changing the
245
- value in `FriendlyId::Configuration::DEFAULTS[:reserved_words]`.
246
-
247
- ## Scoped Slugs
248
-
249
- FriendlyId can generate unique slugs within a given scope. For example, assume
250
- you have an application that displays restaurants. Without scoped slugs, if two
251
- restaurants are named "Joe's Diner," the second one will end up with
252
- "joes-diner--2" as its friendly_id. Using scoped allows you to keep the slug
253
- names unique for each city, so that the second "Joe's Diner" can also have the
254
- slug "joes-diner", as long as it's located in a different city:
255
-
256
- class Restaurant < ActiveRecord::Base
257
- extend FriendlyId
258
- belongs_to :city
259
- friendly_id :name, :use => :scoped, :scope => :city
260
- end
261
-
262
- class City < ActiveRecord::Base
263
- extend FriendlyId
264
- has_many :restaurants
265
- friendly_id :name, :use => :slugged
266
- end
267
-
268
- City.find("seattle").restaurants.find("joes-diner")
269
- City.find("chicago").restaurants.find("joes-diner")
270
-
271
-
272
- The value for the `:scope` key in your model can be a column, or the name of a
273
- relation.
274
-
275
- ### Complications with Scoped Slugs
276
-
277
- #### Finding Records by friendly\_id
278
-
279
- If you are using scopes your friendly ids may not be unique, so a simple find like
280
-
281
- Restaurant.find("joes-diner")
282
-
283
- may return the wrong record. In these cases when you want to use the friendly\_id for queries,
284
- either query as a relation, or specify the scope in your query conditions:
285
-
286
- # will only return restaurants named "Joe's Diner" in the given city
287
- @city.restaurants.find("joes-diner")
288
-
289
- # or
290
-
291
- Restaurants.find("joes-diner").where(:city_id => @city.id)
292
-
293
-
294
- #### Finding All Records That Match a Scoped ID
295
-
296
- If you want to find all records with a particular friendly\_id regardless of scope,
297
- the easiest way is to use cached slugs and query this column directly:
298
-
299
- Restaurant.find_all_by_slug("joes-diner")
300
-
301
- ### Routes for Scoped Models
302
-
303
- Note that FriendlyId does not set up any routes for scoped models; you must do
304
- this yourself in your application. Here's an example of one way to set this up:
305
-
306
- # in routes.rb
307
- resources :cities do
308
- resources :restaurants
309
- end
310
-
311
- # in views
312
- <%= link_to 'Show', [@city, @restaurant] %>
313
-
314
- # in controllers
315
- @city = City.find(params[:city_id])
316
- @restaurant = @city.restaurants.find(params[:id])
317
-
318
- # URL's:
319
- http://example.org/cities/seattle/restaurants/joes-diner
320
- http://example.org/cities/chicago/restaurants/joes-diner
321
-
322
-
323
- # Misc tips
324
-
325
- ## Default Scopes
326
-
327
- Whether you're using FriendlyId or not, a good rule of thumb for default scopes
328
- is to always use your model's table name. Otherwise any time you do a join, you
329
- risk having queries fail because of duplicate column names - particularly for a
330
- default scope like this one:
331
-
332
- default_scope :order => "created_at DESC"
333
-
334
- Instead, do this:
335
-
336
- default_scope :order => = "#{quoted_table_name}.created_at DESC"
337
-
338
- Or even better, unless you're using a custom primary key:
339
-
340
- default_scope :order => = "#{quoted_table_name}.id DESC"
341
-
342
- because sorting by a unique integer column is faster than sorting by a date
343
- column.
344
-
345
- ## Some Benchmarks
346
-
347
- These benchmarks can give you an idea of FriendlyId's impact on the
348
- performance of your application. Of course your results may vary.
349
-
350
- activerecord (3.0.9)
351
- ruby 1.9.2p180 (2011-02-18 revision 30909) [x86_64-darwin10.6.0]
352
- friendly_id (4.0.0.beta1)
353
- sqlite3 (1.3.3) gem
354
- sqlite3 3.6.12 in-memory database
355
-
356
-
357
- user system total real
358
- find (without FriendlyId) 0.300000 0.000000 0.300000 ( 0.306729)
359
- find (in-table slug) 0.350000 0.000000 0.350000 ( 0.351760)
360
- find (external slug) 3.320000 0.000000 3.320000 ( 3.326749)
361
- insert (without FriendlyId) 0.810000 0.010000 0.820000 ( 0.810513)
362
- insert (in-table-slug) 1.740000 0.000000 1.740000 ( 1.743511)
363
- insert (external slug) 3.540000 0.010000 3.550000 ( 3.544898)