UPGRADING.md
## Articles
* [Migrating an ad-hoc URL slug system to FriendlyId](http://olivierlacan.com/posts/migrating-an-ad-hoc-url-slug-system-to-friendly-id/)
* [Pretty URLs with FriendlyId](http://railscasts.com/episodes/314-pretty-urls-with-friendlyid)
## Docs
The most current docs from the master branch can always be found
[here](http://norman.github.io/friendly_id).
Docs for older versions are also available:
* [5.0](http://norman.github.io/friendly_id/5.0/)
* [4.0](http://norman.github.io/friendly_id/4.0/)
* [3.3](http://norman.github.io/friendly_id/3.3/)
* [2.3](http://norman.github.io/friendly_id/2.3/)
## What Changed in Version 5.1
5.1 is a bugfix release, but bumps the minor version because some applications may be dependent
on the previously buggy behavior. The changes include:
* Blank strings can no longer be used as slugs.
* When the first slug candidate is rejected because it is reserved, additional candidates will
now be considered before marking the record as invalid.
* The `:finders` module is now compatible with Rails 4.2.
## What Changed in Version 5.0
As of version 5.0, FriendlyId uses [semantic versioning](http://semver.org/). Therefore, as you might
infer from the version number, 5.0 introduces changes incompatible with 4.0.
The most important changes are:
* Finders are no longer overridden by default. If you want to do friendly finds,
you must do `Model.friendly.find` rather than `Model.find`. You can however
restore FriendlyId 4-style finders by using the `:finders` addon:
```ruby
friendly_id :foo, use: :slugged # you must do MyClass.friendly.find('bar')
# or...
friendly_id :foo, use: [:slugged, :finders] # you can now do MyClass.find('bar')
```
* A new "candidates" functionality which makes it easy to set up a list of
alternate slugs that can be used to uniquely distinguish records, rather than
appending a sequence. For example:
```ruby
class Restaurant < ActiveRecord::Base
extend FriendlyId
friendly_id :slug_candidates, use: :slugged
# Try building a slug based on the following fields in
# increasing order of specificity.
def slug_candidates
[
:name,
[:name, :city],
[:name, :street, :city],
[:name, :street_number, :street, :city]
]
end
end
```
* Now that candidates have been added, FriendlyId no longer uses a numeric
sequence to differentiate conflicting slug, but rather a UUID (e.g. something
like `2bc08962-b3dd-4f29-b2e6-244710c86106`). This makes the
codebase simpler and more reliable when running concurrently, at the expense
of uglier ids being generated when there are conflicts.
* The default sequence separator has been changed from two dashes to one dash.
* Slugs are no longer regenerated when a record is saved. If you want to regenerate
a slug, you must explicitly set the slug column to nil:
```ruby
restaurant.friendly_id # joes-diner
restaurant.name = "The Plaza Diner"
restaurant.save!
restaurant.friendly_id # joes-diner
restaurant.slug = nil
restaurant.save!
restaurant.friendly_id # the-plaza-diner
```
You can restore some of the old behavior by overriding the
`should_generate_new_friendly_id?` method.
* The `friendly_id` Rails generator now generates an initializer showing you
how to do some common global configuration.
* The Globalize plugin has moved to a [separate gem](https://github.com/norman/friendly_id-globalize) (currently in alpha).
* The `:reserved` module no longer includes any default reserved words.
Previously it blocked "edit" and "new" everywhere. The default word list has
been moved to `config/initializers/friendly_id.rb` and now includes many more
words.
* The `:history` and `:scoped` addons can now be used together.
* Since it now requires Rails 4, FriendlyId also now requires Ruby 1.9.3 or
higher.
## Upgrading from FriendlyId 4.0
Run `rails generate friendly_id --skip-migration` and edit the initializer
generated in `config/initializers/friendly_id.rb`. This file contains notes
describing how to restore (or not) some of the defaults from FriendlyId 4.0.
If you want to use the `:history` and `:scoped` addons together, you must add a
`:scope` column to your friendly_id_slugs table and replace the unique index on
`:slug` and `:sluggable_type` with a unique index on those two columns, plus
the new `:scope` column.
A migration like this should be sufficient:
```ruby
add_column :friendly_id_slugs, :scope, :string
remove_index :friendly_id_slugs, [:slug, :sluggable_type]
add_index :friendly_id_slugs, [:slug, :sluggable_type]
add_index :friendly_id_slugs, [:slug, :sluggable_type, :scope], unique: true
```