Introduction to Mobility v1.0 - shioyama/mobility GitHub Wiki
This page documents changes (mostly in configuration) between the latest 0.8 release and 1.0.
TL;DR
If you just want to update to 1.0 from an earlier version, update your Mobility.configure
code to look like the one in the new initializer template.
Previously, inside the Mobility.configure
block, you would call various configuration methods on the config
. Instead, you now call plugins
and in a block explicitly declare each plugin you want to use, along with any default (this replaces the default_options
hash).
So suppose you had a configuration like this (in 0.8.x):
Mobility.configure do |config|
config.default_backend = :key_value
config.accessor_method = :translates
config.query_method = :i18n
config.default_options[:fallbacks] = true
config.default_options[:type] = :text
end
It's important to realize here that default_options
mixes plugin defaults and backend defaults. In 1.0, these are now separated, so you must pass any options related to the backend to the backend
option in your declared plugins.
Also, Mobility previously quietly enabled the cache
and presence
plugins even if you did not explicitly ask for them. To get the same behaviour, you will need to specify them explicitly now.
In addition, Mobility v1.0 now breaks down many things that were previously combined. So when you enable the backend
plugin, it only adds hooks and a mobility_backends
method returning a hash of backends. To actually get reader and writer methods, you need to also include the reader
and writer
plugins. To also get methods returning the backend for a particular attribute (title_backend
for the title
backend), you need to also include the backend_reader
plugin.
Finally, accessor_method
is no longer supported (and you probably never used it, so safe to ignore).
So with that in mind, this configuration would be rewritten as follows:
Mobility.configure do
plugins do
backend :key_value, type: :text # default_options[:type] is a backend option, so it must be passed to the `backend` plugin
reader # Explicitly declare readers,
writer # writers, and
backend_reader # backend reader (post.title_backend, etc).
active_record # You must now also explicitly ask for ActiveRecord (or Sequel)
query # i18n is the default scope
cache # previously implicit
fallbacks
presence # previously implicit
default # previously implicit
# attribute_methods # uncomment this to get methods like `translated_attributes`
end
end
If you get an exception about an invalid option key, there are two possible issues:
- you are passing a key, say
dirty: true
, but you have not enabled thedirty
plugin (just adddirty
in the list above - you are passing a key for a backend, but the backend does not accept that key. A common case of this is passing
type
to a backend other than KeyValue, since no other backends define atype
, and Mobility will now see this and complain.
Details of what changed
Configuration
Previously, Mobility had a Mobility::Configuration
class with settings such as default_backend
, accessor_method
and query_method
. These were global settings which could be accessed from any backend or plugin.
Similarly, while plugins existed, they were mostly implicitly included (fallbacks, dirty tracking, etc) and could only be "disabled" by passing a falsey value to translates
, e.g. dirty: false
. While this disabled them, the plugin was still present.
With 1.0, everything is centralized around plugins, none of which are included unless you ask for them. (This means that specs can also test conditions in complete isolation.)
So while the syntax looks similar, when you now call:
Mobility.configure do
# ...
... the context in the block here is an instance of Mobility::Translations
(previously Mobility::Attributes
), with some methods to declare and customize plugins. You call plugins
to declare plugins, with optional default settings.
Here is how we would set the default backend to :key_value
and enable fallbacks and dirty tracking:
Mobility.configure do
plugins do
backend :key_value
fallbacks
dirty
end
end
Plugins can have dependencies and those dependencies will be resolved inside the plugins
block.
ORM plugin must be explicitly enabled
In the same spirit of making things more explicit, Mobility no longer inspects constants to figure out which ORM you're using; instead, you just declare the active_record
or sequel
plugin:
Mobility.configure do
plugins do
backend :key_value
active_record # or sequel
# ...
end
end
Options are validated against plugins and backend options
Previously, you could pass any options to translates
and if they were not used, they would be ignored. Now Mobility will complain if it sees a key it does not expect.
There are two contexts where this may happen, the first is when calling translates
(or Mobility::Translations.new
) and passing an option like dirty
, but without actually enabling the dirty
plugin. In this case, just add dirty
to the list of plugins in Mobility.configure
.
The second is if you pass an option to the backend in your configuration, but the backend does not accept that option. e.g.
Mobility.configure do
plugins do
backend :key_value, foo: 'bar'
end
end
foo
is not an option of the KeyValue backend, so Mobility will blow up with an exception. Just remove it. A common case of this is passing type
to a backend other than the KeyValue backend.
Some (mostly internal) namespaces have changed
Previously, backends used namespaces like Mobility::ActiveRecord
, Mobility::Arel
and Mobility::Sequel
. As of 1.0, the top namespace is kept very minimal with everything specific going under Mobility::Plugins
and/or Mobility::Backends
. Aside from keeping Mobility clean, it also avoids naming conflicts with other gems (see #258).
This may affect you if you are referring to constants like Mobility::ActiveRecord::TextTranslation
or Mobility::ActiveRecord::StringTranslation
(in the KeyValue backend), or similar classes in Sequel.
In general, if you get a NameErrror
, the class name has probably changed to now be namespaced under Mobility::Backends
, according to the backend that uses it:
Mobility::ActiveRecord::StringTranslation
becomesMobility::Backends::ActiveRecord::KeyValue::StringTranslation
Mobility::ActiveRecord::TextTranslation
becomesMobility::Backends::ActiveRecord::Table::TextTranslation
- etc
For other details, see changes in #464.