Giter Site home page Giter Site logo

Comments (5)

pwim avatar pwim commented on May 18, 2024

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.

shioyama avatar shioyama commented on May 18, 2024

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.

pwim avatar pwim commented on May 18, 2024

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.

shioyama avatar shioyama commented on May 18, 2024

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.

shioyama avatar shioyama commented on May 18, 2024

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 the fallback: :en option to the reader)
  • disabled by default, but included (in this case, post.title will not apply fallbacks, but post.title(fallback: :en) would work using :en as fallback since the fallback plugin would be included.
  • enabled (post.title applies default fallbacks and post.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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.