Mobility support for FriendlyId.
Add this line to your application's Gemfile:
gem 'friendly_id-mobility', '~> 1.0.4'
And then execute:
bundle
Then run the Mobility generator:
rails generate mobility:install
This will generate an initializer for Mobility. To ensure that FriendlyId sees
changes correctly on attributes, enable (uncomment) the dirty
plugin line in
your Mobility configuration:
Mobility.configure do
plugins do
# ...
dirty
# ...
end
end
Next, run the FriendlyId generator:
rails generate friendly_id
And migrate to generate Mobility and FriendlyId tables:
rake db:migrate
You're ready to go!
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.
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
journalists
table named name
):
class Journalist < ActiveRecord::Base
extend Mobility
translates :slug
extend FriendlyId
friendly_id :name, 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.
You can also translate both slug and base attribute:
class Article < ActiveRecord::Base
extend Mobility
translates :slug, :title
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"
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 ...>
Note that this gem is not compatible with the finders
add-on; using both
together will lead to unexpected results. To use these finder methods, you will
have to remove finders
and explicitly call friendly.find
, as above.
To use the FriendlyId history module, use use: [:history, :mobility]
when
calling friendly_id
from your model:
class Article < ActiveRecord::Base
extend Mobility
translates :slug, :title
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
.
The gem is available as open source under the terms of the MIT License.