FriendlyId Mobility
Mobility support for FriendlyId.
Installation
Add this line to your application's Gemfile:
gem 'friendly_id-mobility', '~> 0.3.1'
And then execute:
bundle
Or install it yourself as:
gem install friendly_id-mobility
Run the Mobility generator:
rails generate mobility:install
Run the FriendlyId generator:
rails generate friendly_id
And migrate to generate Mobility and FriendlyId tables:
rake db:migrate
You're ready to go!
Usage
There are two ways to translate FriendlyId slugs with Mobility: with an untranslated base column (like the SimpleI18n module included with FriendlyId), and with a translated base column.
Translating Slug
If you only want to translate the slug, include Mobility
and translate the
slug with whichever backend you want (here we're assuming the default KeyValue
backend). Here, name
is untranslated (so there is a column on the posts
table named name
):
class Journalist < ActiveRecord::Base
include Mobility
translates :slug
extend FriendlyId
friendly_id :title, use: :mobility
end
You can now save name
and generate a slug, and update the slug in any locale
using set_friendly_id
journalist = Journalist.create(name: "John Smith")
journalist.slug
#=> "john-smith"
journalist.set_friendly_id("Juan Fulano", :es)
journalist.save!
I18n.with_locale(:es) { journalist.friendly_id }
#=> "juan-fulano"
So the slug is translated, but the base attribute (name
) is not.
Translating Slug and Base Attribute
You can also translate both slug and base attribute:
class Article < ActiveRecord::Base
include Mobility
translates :slug, :title, dirty: true
extend FriendlyId
friendly_id :title, use: :mobility
end
In this case, title
is translated, and its value in the current locale will
be used to generate the slug in this locale:
article = Article.create(title: "My Foo Title")
article.title
#=> "My Foo Title"
article.slug
#=> "my-foo-title"
Mobility.locale = :fr
article.title = "Mon titre foo"
article.save
article.slug
#=> "mon-titre-foo"
Mobility.locale = :en
article.slug
#=> "my-foo-title"
Setting dirty: true
on the translated base attribute is recommended in order
to ensure that changes in any locale trigger updates to the slug in that
locale.
Friendly Finders with Translated Attributes
The Mobility i18n
scope is mixed into the friendly
scope for models which
use: :mobility
, so you can find translated slugs just like you would an
untranslated one:
Mobility.locale = :en
Article.friendly.find("my-foo-title")
#=> #<Article id: 1 ...>
Mobility.locale = :fr
Article.friendly.find("mon-titre-foo")
#=> #<Article id: 1 ...>
Slug History
To use the FriendlyId history module, use use: [:history, :mobility]
when
calling friendly_id
from your model:
class Article < ActiveRecord::Base
include Mobility
translates :slug, :title, dirty: true
extend FriendlyId
friendly_id :title, use: [:history, :mobility]
end
It is important to have :history
before :mobility
here, since the
Mobility module looks for the presence of the history module and only adds
necessary overrides if history has been enabled (so the reverse order will not
work).
To use the history feature, you must add a locale
column to your
friendly_id_slugs
table, which you can do with the friendly_id_mobility
generator:
rails generate friendly_id_mobility
Then run the generated migration with rake db:migrate
.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/shioyama/friendly_id-mobility. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
License
The gem is available as open source under the terms of the MIT License.