Comments (5)
An alternative approach would be to configure the default behavior within the plugin itself, instead of having a default default_options.
For instance,
module Presence
def self.apply(attributes, option)
attributes.backend_class.include(self) if option != false
end
end
In the previous example, if the user didn't specify anything, option
would be nil
, so the plugin would be enabled. If a user explicitly sets presence: false
, then the plugin would be disabled.
The only downside to this approach is that given the current implementation, there is no way to tell if the user specified presence: nil
. That's probably not a big deal, but if it is an issue, you could initialize the plugins like
Mobility.plugins.each do |name|
plugin = get_plugin_class(name)
plugin.apply(self, !options.has_key?(name), options[name])
end
and change the method signature of apply to
def self.apply(attributes, default, option)
One advantage of this approach is it keeps the default behaviour of a plugin contained within the plugin itself.
from mobility.
Yes I thought about that as one way to do it. The issue I have is that checking for false
is not really a good pattern IMHO. The option should really be true
or false
.
One advantage of this approach is it keeps the default behaviour of a plugin contained within the plugin itself.
In a way, yes, but on the other hand it means looking at the default_options
hash alone is not enough to get a clear idea of what is on by default and what is off. Whereas if true
universally means "on", then just looking at the default options hash you get a clear idea of what is enabled and what is not.
So personally I prefer having a set of defaults in Mobility.default_options
and have the ability to reset each one per-key.
That said, the plugins are not consistent in the sense of true/false above. I think actually fallbacks
should be false
by default (same as above, but for consistency).
from mobility.
I see your point. Raising visibility to what options are enabled by default is important. One other approach you probably also considered was having rails generate mobility:install
just generate a config that has setup like
Mobility.configure do |config|
config.default_options = {
cache: true,
dirty: false,
fallbacks: nil,
presence: true,
default: nil
}
end
That way, it would be quite obvious how to configure mobility.
The main downside to that approach is maintainability, as it makes it harder to change defaults per version, or guarantee that keys are set.
from mobility.
Yes, that would be another way to do it. I'm worried like you said about maintainability though. If we use this approach, and in future release we have another plugin that should be on by default, we'll have the same problem again.
from mobility.
Actually, looking at the plugins again, I remember now why fallbacks
is nil
and not false
.
The tricky thing is that with a plugin like fallbacks, you really have three different things you may want:
- disable the plugin entirely so that it is not even included into the backend (in the case of fallbacks, this would mean that even
post.title(fallback: :en)
would not work, since no plugin would even receive thefallback: :en
option to the reader) - disabled by default, but included (in this case,
post.title
will not apply fallbacks, butpost.title(fallback: :en)
would work using:en
as fallback since the fallback plugin would be included. - enabled (
post.title
applies default fallbacks andpost.title(fallback: :en)
overrides the default fallbacks to use a different fallback locale)
You could argue that the first case (disable the plugin altogether) can also be achieved by removing fallbacks
from Mobility.plugins
, which is the array that Mobility iterates through when applying plugins:
Mobility.plugins.each do |name|
plugin = get_plugin_class(name)
plugin.apply(self, options[name])
end
However, this applies universally and you may just want to remove the fallbacks plugin from a particular model (say for debugging). So here false
meaning something different from nil
happens to be useful.
The default
plugin also has a nil
option value by default. This one is tricky since the option value is the default, so here the plugin is included regardless of the option value. To absolutely disable it (not even include it into the backend) you actually do need to remove it from the Mobility.plugins
array, and thus remove it from all models.
So this whole options thing is slightly more complicated than I'd like it to be, but after thinking about this quite a lot (and simplifying things quite a lot from 0.1 to 0.2) this is the most straightforward setup I've managed to come up with. At least, the application of plugins is very simple (the four lines of code pasted above).
Sorry a bit of a digression... but if you have thoughts, interested to hear
from mobility.
Related Issues (20)
- Use mobility with StoreModel HOT 2
- Issue with backend extention HOT 1
- reader & locale_accessors won't return correct translation, but backend_reader does HOT 5
- Destruction of DB records with linked translation records fails (with a strange SQL query) HOT 2
- Model attribute defined fallback HOT 2
- Error when ordering and selecting distinct on translated resource HOT 2
- Marks object as dirty even if nothing was changed in RichTextTranslation fields HOT 5
- Cache issue with JSONb (+locale_accessors) & ActiveRecord HOT 2
- Using a query method block does not automatically scope to i18n HOT 1
- Translated inputs are empty after failed form validation in a specific setup HOT 1
- Automatic ActionText `rich_text` detection failing when operating on locale-dependent mobility field HOT 1
- Any accepted way to store images working with active storage ? HOT 1
- Unique Validation didn't work with locale_accessors on every locales HOT 1
- Not compatible with FastGettext - request for string available locale support HOT 2
- Error when installing on Vitess MySQL db HOT 4
- The presence plugin doesn't work as expected HOT 1
- Destruction of record+translations fails, when model IDs are of the type "varchar(36)" (a UUID string) HOT 3
- accessor super method doesn't work with arguments like class.value(locale: :de) HOT 1
- ordering by specific locale HOT 2
- Add type checking plugin reference HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from mobility.