friendly_id 4.1.0.beta.1 → 5.0.0.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44f9c1a8ef2afb5bda90485d0df78b67da83e73d
4
+ data.tar.gz: 722909dc863dd55275aa403ee4321c99af1ea118
5
+ SHA512:
6
+ metadata.gz: d0949ad9c3d10238bbc4f6f350bd4d8b7101485679f3d55ef78c902b1a0f280d738b89f5753bd467d593ab8ec91ca7bc412323083114140f1fea5a061c27755f
7
+ data.tar.gz: d561df0002650904d1b087185f9d5a94ad6e191ab88925fe9e0974894affaafa55e92db2774cc3fe364ead7fef85dd6cade495f7f47feeeda54efe5b04b2681e
@@ -1,20 +1,15 @@
1
+ language: ruby
1
2
  rvm:
3
+ - 2.0.0
2
4
  - 1.9.3
3
- - 1.8.7
4
- # - jruby
5
- # - rbx
6
-
7
- branches:
8
- only:
9
- - master
5
+ # - jruby-19mode
6
+ # - rbx-19mode
10
7
  env:
11
8
  - DB=postgres
12
9
  - DB=mysql
13
10
  - DB=sqlite3
14
-
15
11
  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'
12
+ - gemfiles/Gemfile.rails-4.0.rb
13
+
14
+ before_script: 'bundle exec rake db:create db:up'
20
15
  script: 'bundle exec rake test'
@@ -10,6 +10,10 @@ suggestions, ideas and improvements to FriendlyId.
10
10
 
11
11
  Made the :scoped and :history modules compatible with each other (Andre Duffeck)
12
12
 
13
+ ## 4.0.10 (NOT RELEASED YET)
14
+
15
+ * Fixed table prefixes/suffixes being ignored (Jesse Farless)
16
+
13
17
  ## 4.0.9 (2012-10-31)
14
18
 
15
19
  * Fixed support for Rails 3.2.9.rc1
data/Gemfile CHANGED
@@ -1,11 +1,11 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
5
  # Database Configuration
6
6
  group :development, :test do
7
7
  platforms :jruby do
8
- gem 'activerecord-jdbcsqlite3-adapter'
8
+ gem 'activerecord-jdbcsqlite3-adapter', '>= 1.3.0.beta2'
9
9
  gem 'jruby-openssl'
10
10
  end
11
11
 
data/Guide.rdoc CHANGED
@@ -114,9 +114,8 @@ store them in a field in your model. By default, this field must be named
114
114
  +:slug+, though you may change this using the
115
115
  {FriendlyId::Slugged::Configuration#slug_column slug_column} configuration
116
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.
117
+ unique. You may also wish to constrain it to NOT NULL, but this depends on your
118
+ app's behavior and requirements.
120
119
 
121
120
  === Example Setup
122
121
 
@@ -165,11 +164,11 @@ FriendlyId will append a sequence to the generated slug to ensure uniqueness:
165
164
  car2 = Car.create :title => "Peugot 206"
166
165
 
167
166
  car.friendly_id #=> "peugot-206"
168
- car2.friendly_id #=> "peugot-206--2"
167
+ car2.friendly_id #=> "peugot-206-f9f3789a-daec-4156-af1d-fab81aa16ee5"
169
168
 
170
169
  ==== Sequence Separator - The Two Dashes
171
170
 
172
- By default, FriendlyId uses two dashes to separate the slug from a sequence.
171
+ By default, FriendlyId uses a dash to separate the slug from a sequence.
173
172
 
174
173
  You can change this with the {FriendlyId::Slugged::Configuration#sequence_separator
175
174
  sequence_separator} configuration option.
@@ -268,11 +267,11 @@ second, in concurrent code, either in threads or multiple processes.
268
267
 
269
268
  To solve the nested attributes issue, I recommend simply avoiding them when
270
269
  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.
270
+ Github issue}[https://github.com/FriendlyId/friendly_id/issues/185] for discussion.
272
271
 
273
272
  To solve the concurrency issue, I recommend locking the model's table against
274
273
  inserts while when saving the record. See {this Github
275
- issue}[https://github.com/norman/friendly_id/issues/180] for discussion.
274
+ issue}[https://github.com/FriendlyId/friendly_id/issues/180] for discussion.
276
275
 
277
276
 
278
277
  == History: Avoiding 404's When Slugs Change
@@ -296,6 +295,8 @@ model.
296
295
 
297
296
  === Considerations
298
297
 
298
+ This module is incompatible with the +:scoped+ module.
299
+
299
300
  Because recording slug history requires creating additional database records,
300
301
  this module has an impact on the performance of the associated model's +create+
301
302
  method.
@@ -350,13 +351,32 @@ This allows, for example, two restaurants in different cities to have the slug
350
351
  City.find("chicago").restaurants.find("joes-diner")
351
352
 
352
353
  Without :scoped in this case, one of the restaurants would have the slug
353
- +joes-diner+ and the other would have +joes-diner--2+.
354
+ +joes-diner+ and the other would have +joes-diner-f9f3789a-daec-4156-af1d-fab81aa16ee5+.
354
355
 
355
356
  The value for the +:scope+ option can be the name of a +belongs_to+ relation, or
356
357
  a column.
357
358
 
358
- Please do note that you must drop the uniqueness constraint on the slug's
359
- column in the database when you're scoping the slug.
359
+ Additionally, the +:scope+ option can receive an array of scope values:
360
+
361
+ class Cuisine < ActiveRecord::Base
362
+ extend FriendlyId
363
+ has_many :restaurants
364
+ friendly_id :name, :use => :slugged
365
+ end
366
+
367
+ class City < ActiveRecord::Base
368
+ extend FriendlyId
369
+ has_many :restaurants
370
+ friendly_id :name, :use => :slugged
371
+ end
372
+
373
+ class Restaurant < ActiveRecord::Base
374
+ extend FriendlyId
375
+ belongs_to :city
376
+ friendly_id :name, :use => :scoped, :scope => [:city, :cuisine]
377
+ end
378
+
379
+ All supplied values will be used to determine scope.
360
380
 
361
381
  === Finding Records by Friendly ID
362
382
 
@@ -417,7 +437,7 @@ must also include the locale in its name.
417
437
 
418
438
  This module is most suitable to applications that need to support few locales.
419
439
  If you need to support two or more locales, you may wish to use the
420
- {FriendlyId::Globalize Globalize} module instead.
440
+ friendly_id_globalize gem instead.
421
441
 
422
442
  === Example migration
423
443
 
@@ -465,56 +485,7 @@ If you don't pass in a locale argument, FriendlyId::SimpleI18n will just use the
465
485
  current locale:
466
486
 
467
487
  I18n.with_locale(:es) do
468
- post.set_friendly_id("la-guerra-de-las-galaxas")
469
- end
470
-
471
-
472
- == Translating Slugs Using Globalize
473
-
474
- The {FriendlyId::Globalize Globalize} module lets you use
475
- Globalize[https://github.com/svenfuchs/globalize3] to translate slugs. This
476
- module is most suitable for applications that need to be localized to many
477
- languages. If your application only needs to be localized to one or two
478
- languages, you may wish to consider the {FriendlyId::SimpleI18n SimpleI18n}
479
- module.
480
-
481
- In order to use this module, your model's table and translation table must both
482
- have a slug column, and your model must set the +slug+ field as translatable
483
- with Globalize:
484
-
485
- class Post < ActiveRecord::Base
486
- translates :title, :slug
487
- extend FriendlyId
488
- friendly_id :title, :use => :globalize
489
- end
490
-
491
- === Finds
492
-
493
- Finds will take the current locale into consideration:
494
-
495
- I18n.locale = :it
496
- Post.find("guerre-stellari")
497
- I18n.locale = :en
498
- Post.find("star-wars")
499
-
500
- To find a slug by an explicit locale, perform the find inside a block
501
- passed to I18n's +with_locale+ method:
502
-
503
- I18n.with_locale(:it) do
504
- Post.find("guerre-stellari")
505
- end
506
-
507
- === Creating Records
508
-
509
- When new records are created, the slug is generated for the current locale only.
510
-
511
- === Translating Slugs
512
-
513
- To translate an existing record's friendly_id, simply change the locale and
514
- assign a value to the +slug+ field:
515
-
516
- I18n.with_locale(:it) do
517
- post.slug = "guerre-stellari"
488
+ post.set_friendly_id("La guerra de las galaxas")
518
489
  end
519
490
 
520
491
 
@@ -546,6 +517,6 @@ For example:
546
517
  after_validation :move_friendly_id_error_to_name
547
518
 
548
519
  def move_friendly_id_error_to_name
549
- errors.messages[:name] = errors.messages.delete(:friendly_id)
520
+ errors.add :name, *errors.delete(:friendly_id) if errors[:friendly_id].present?
550
521
  end
551
- end
522
+ end
data/README.md CHANGED
@@ -1,6 +1,17 @@
1
1
  # FriendlyId
2
2
 
3
- [![Build Status](https://travis-ci.org/norman/friendly_id.png)](https://travis-ci.org/norman/friendly_id)
3
+ **VERSION NOTE**
4
+
5
+ **Rails 4**:
6
+ Master branch of this repository contains FriendlyId 5 which is compatible with Rails 4.
7
+ This version is under active development and not yet fully stable.
8
+
9
+ **Rails 3**:
10
+ If you wish to use this gem with Rails 3.1 or 3.2 you need to use FriendlyId version 4, which is the current stable release.
11
+ Please see [4.0-stable
12
+ branch](https://github.com/FriendlyId/friendly_id/tree/4.0-stable).
13
+
14
+ [![Build Status](https://travis-ci.org/FriendlyId/friendly_id.png)](https://travis-ci.org/FriendlyId/friendly_id)
4
15
 
5
16
  FriendlyId is the "Swiss Army bulldozer" of slugging and permalink plugins for
6
17
  Ruby on Rails. It allows you to create pretty URLs and work with human-friendly
@@ -18,63 +29,125 @@ instead of:
18
29
  ## FriendlyId Features
19
30
 
20
31
  FriendlyId offers many advanced features, including: slug history and
21
- versioning, i18n, Globalize support, scoped slugs, reserved words, and custom
22
- slug generators.
32
+ versioning, i18n, scoped slugs, reserved words, and custom slug generators.
23
33
 
24
- FriendlyId is compatible with Active Record **3.0** and higher.
34
+ Note: FriendlyId 5.0 is compatible with Active Record **4.0** and higher only.
35
+ For Rails 3.x, please use FriendlyId 4.x.
25
36
 
26
- ## Version 4.x
27
37
 
28
- FriendlyId 4.x introduces many changes incompatible with 3.x. If you're
29
- upgrading, please [read the
30
- docs](http://rubydoc.info/github/norman/friendly_id/master/file/WhatsNew.md) to see what's
31
- new.
38
+ ## Version 5.x
32
39
 
33
- ## Docs
40
+ As of version 5.0, FriendlyId uses semantic versioning. Therefore, as you might
41
+ infer from the version number, FriendlyId 5.0 introduces changes incompatible
42
+ with 4.x.
34
43
 
35
- The current docs can always be found
36
- [here](http://rubydoc.info/github/norman/friendly_id/master/frames).
44
+ Here's a summary of the most important changes:
37
45
 
38
- The best place to start is with the
39
- [Guide](http://rubydoc.info/github/norman/friendly_id/master/file/Guide.rdoc),
40
- which compiles the top-level RDocs into one outlined document.
46
+ * FriendlyId no longer overrides `find`. If you want to do friendly finds, you
47
+ must do `Model.friendly.find` rather than `Model.find`.
41
48
 
42
- You might also want to watch Ryan Bates's [Railscast on FriendlyId](http://railscasts.com/episodes/314-pretty-urls-with-friendlyid).
49
+ * Version 5.0 offers a new "candidates" functionality which makes it easy to
50
+ set up a list of alternate slugs that can be used to uniquely distinguish
51
+ records, rather than appending a sequence. For example:
43
52
 
44
- ## Rails Quickstart
53
+ ```ruby
54
+ class Restaurant < ActiveRecord::Base
55
+ extend FriendlyId
56
+ friendly_id :slug_candidates, use: :slugged
45
57
 
46
- gem install friendly_id
58
+ # Try building a slug based on the following fields in
59
+ # increasing order of specificity.
60
+ def slug_candidates
61
+ [
62
+ :name,
63
+ [:name, :city],
64
+ [:name, :street, :city],
65
+ [:name, :street_number, :street, :city]
66
+ ]
67
+ end
68
+ end
69
+ ```
47
70
 
48
- rails new my_app
71
+ * Now that candidates have been added, FriendlyId no longer uses a numeric
72
+ sequence to differentiate conflicting slug, but rather a GUID. This makes the
73
+ codebase simpler and more reliable when running concurrently, at the expense
74
+ of uglier ids being generated when there are conflicts.
49
75
 
50
- cd my_app
76
+ * The Globalize module has been removed and will be released as its own gem.
77
+ Note that it has not yet been developed.
51
78
 
52
- gem "friendly_id", "~> 4.0.1"
79
+ * The default sequence separator is now `-` rather than `--`.
53
80
 
54
- rails generate scaffold user name:string slug:string
81
+ * Slugs are no longer regenerated when a record is saved. If you want to regenerate
82
+ a slug, you must explicitly set the slug column to nil:
55
83
 
56
- # edit db/migrate/*_create_users.rb
57
- add_index :users, :slug, unique: true
84
+ ```ruby
85
+ restaurant.friendly_id # joes-diner
86
+ restaurant.name = "The Plaza Diner"
87
+ restaurant.save!
88
+ restaurant.friendly_id # joes-diner
89
+ restaurant.slug = nil
90
+ restaurant.save!
91
+ restaurant.friendly_id # the-plaza-diner
92
+ ```
58
93
 
59
- rake db:migrate
94
+ * Like Rails 4, FriendlyId now requires Ruby 1.9.3 or higher.
60
95
 
61
- # edit app/models/user.rb
62
- class User < ActiveRecord::Base
63
- extend FriendlyId
64
- friendly_id :name, use: :slugged
65
- end
96
+ ## Docs
66
97
 
67
- User.create! name: "Joe Schmoe"
98
+ The current docs can always be found
99
+ [here](http://rubydoc.info/github/FriendlyId/friendly_id/master/frames).
68
100
 
69
- rails server
101
+ The best place to start is with the
102
+ [Guide](http://rubydoc.info/github/FriendlyId/friendly_id/master/file/Guide.rdoc),
103
+ which compiles the top-level RDocs into one outlined document.
70
104
 
71
- GET http://localhost:3000/users/joe-schmoe
105
+ You might also want to watch Ryan Bates's [Railscast on FriendlyId](http://railscasts.com/episodes/314-pretty-urls-with-friendlyid),
106
+ which is now somewhat outdated but still mostly relevant.
72
107
 
73
- # If you're adding FriendlyId to an existing app and need
74
- # to generate slugs for existing users, do this from the
75
- # console, runner, or add a Rake task:
76
- User.find_each(&:save)
108
+ ## Rails Quickstart
77
109
 
110
+ ```shell
111
+ rails new my_app
112
+ cd my_app
113
+ ```
114
+ ```ruby
115
+ # Gemfile
116
+ gem 'friendly_id', github: 'FriendlyId/friendly_id', branch: 'master' # Note: You MUST use 5.0.0 or greater for Rails 4.0+
117
+ ```
118
+ ```shell
119
+ rails generate scaffold user name:string slug:string
120
+ ```
121
+ ```ruby
122
+ # edit db/migrate/*_create_users.rb
123
+ add_index :users, :slug, unique: true
124
+ ```
125
+ ```shell
126
+ rake db:migrate
127
+ ```
128
+ ```ruby
129
+ # edit app/models/user.rb
130
+ class User < ActiveRecord::Base
131
+ extend FriendlyId
132
+ friendly_id :name, use: :slugged
133
+ end
134
+
135
+ User.create! name: "Joe Schmoe"
136
+
137
+ # Change User.find to User.friendly.find in your controller
138
+ User.friendly.find(params[:id])
139
+ ```
140
+ ```shell
141
+ rails server
142
+
143
+ GET http://localhost:3000/users/joe-schmoe
144
+ ```
145
+ ```ruby
146
+ # If you're adding FriendlyId to an existing app and need
147
+ # to generate slugs for existing users, do this from the
148
+ # console, runner, or add a Rake task:
149
+ User.find_each(&:save)
150
+ ```
78
151
 
79
152
  ## Benchmarks
80
153
 
@@ -85,7 +158,7 @@ The latest benchmarks for FriendlyId are maintained
85
158
  ## Bugs
86
159
 
87
160
  Please report them on the [Github issue
88
- tracker](http://github.com/norman/friendly_id/issues) for this project.
161
+ tracker](http://github.com/FriendlyId/friendly_id/issues) for this project.
89
162
 
90
163
  If you have a bug to report, please include the following information:
91
164
 
@@ -103,32 +176,15 @@ article](http://yourbugreportneedsmore.info/).
103
176
  ## Thanks and Credits
104
177
 
105
178
  FriendlyId was originally created by Norman Clarke and Adrian Mugnolo, with
106
- significant help early in its life by Emilio Tagua. I'm deeply grateful for the
107
- generous contributions over the years from [many
108
- volunteers](https://github.com/norman/friendly_id/contributors).
109
-
110
- Part of the inspiration to rework FriendlyId came from Darcy Laycock's library
111
- [Slugged](https://github.com/Sutto/slugged), which he was inspired to create
112
- because of frustrations he experienced while using FriendlyId 3.x. Seeing a
113
- smart programmer become frustrated with my code was enough of a kick in the
114
- butt to make me want to significantly improve this library.
115
-
116
- Many thanks to him for providing valid, real criticism while still being a cool
117
- about it. I definitely recommend you check out his library if for some reason
118
- FriendlyId doesn't do it for you.
119
-
120
- Thanks also to Loren Segal and Nick Plante for YARD and the
121
- [rubydoc.info](http://rubydoc.info/) website which FriendlyId uses for
122
- documentation.
179
+ significant help early in its life by Emilio Tagua. It is now maintained by
180
+ Norman Clarke and Philip Arndt.
123
181
 
124
- Lastly, FriendlyId uses [Travis](http://travis-ci.org/) for continuous
125
- integration. It's an excellent, free service created by a whole bunch of [good
126
- people](https://github.com/travis-ci) - if you're not already using it, you
127
- should be!
182
+ We're deeply grateful for the generous contributions over the years from [many
183
+ volunteers](https://github.com/FriendlyId/friendly_id/contributors).
128
184
 
129
185
  ## License
130
186
 
131
- Copyright (c) 2008-2012 Norman Clarke and contributors, released under the MIT
187
+ Copyright (c) 2008-2013 Norman Clarke and contributors, released under the MIT
132
188
  license.
133
189
 
134
190
  Permission is hereby granted, free of charge, to any person obtaining a copy of
data/Rakefile CHANGED
@@ -15,23 +15,28 @@ Rake::TestTask.new do |t|
15
15
  t.verbose = true
16
16
  end
17
17
 
18
+ desc "Remove temporary files"
18
19
  task :clean do
19
20
  %x{rm -rf *.gem doc pkg coverage}
20
21
  %x{rm -f `find . -name '*.rbc'`}
21
22
  end
22
23
 
24
+ desc "Build the gem"
23
25
  task :gem do
24
26
  %x{gem build friendly_id.gemspec}
25
27
  end
26
28
 
29
+ desc "Build YARD documentation"
27
30
  task :yard => :guide do
28
31
  puts %x{bundle exec yard}
29
32
  end
30
33
 
34
+ desc "Run benchmarks"
31
35
  task :bench => :load_path do
32
36
  require File.expand_path("../bench", __FILE__)
33
37
  end
34
38
 
39
+ desc "Generate Guide.rdoc"
35
40
  task :guide do
36
41
  def read_comments(path)
37
42
  path = File.expand_path("../#{path}", __FILE__)
@@ -47,7 +52,6 @@ task :guide do
47
52
  buffer << read_comments("lib/friendly_id/history.rb")
48
53
  buffer << read_comments("lib/friendly_id/scoped.rb")
49
54
  buffer << read_comments("lib/friendly_id/simple_i18n.rb")
50
- buffer << read_comments("lib/friendly_id/globalize.rb")
51
55
  buffer << read_comments("lib/friendly_id/reserved.rb")
52
56
 
53
57
  File.open("Guide.rdoc", "w") do |file|