A lot of the built-in Rails classes have configuration options that can be set in environment.rb, but there doesn't seem to be any standard way of doing the same thing for your own classes. The following are my initial thoughts on solving this, some simple code, and a few related questions.

Let's say I have a model called MyModel. In MyModel, I'd like to be able to do something like this:

  class MyModel
    include Configurable

    config_attr :example_attribute, "Here's a default value"

    def my_method
      p config.example_attribute
    end
  end

Then, in environment.rb:

  MyModel.configure do
    self.example_attribute = "Here's the configured value"
  end

There's code at the end of the e-mail to implement a simple version of this.


The questions:

1) How do I work around reloadable classes?

The old Rails approach to adding configuration was:

  class MyModel
    @@example_attribute = "Here's a default value"
    cattr_accessor :example_attribute
  end

and in environment.rb:

  MyModel.example_attribute = "Here's the configured value"

This dies for model classes because MyModel is trashed and reloaded on each request, overwriting the value set in environment.rb with the default one after the first request. My code below suffers from the same problem.

Anyone got any ideas on neat ways to work around this? I can think of a couple of approaches, but they're all really ugly.


2) Would something along these lines be a possibility for inclusion in a future version of Rails? I know it's far from being rocket science, but with the proliferation of plugins, engines, etc. it would be nice to have a standard way that this is done, if only so that you know where to look for configuration when using third-party code.


3) What do people think of the API approach I've suggested? I'm trying to make it as simple as possible, not force you to manually define a separate class or module just to hold configuration, but still do strict config checking in environment.rb.


Cheers,

Pete Yandell


  module Configurable
    def self.included(base)
      base.class_eval do
        @@config = Class.new unless defined?(@@config)
        cattr_reader :config
      end

      base.extend(ClassMethods)
    end

    module ClassMethods
      def config_attr(name, value)
        config.cattr_accessor name
        config.send("#{name.to_s}=".to_sym, value)
      end

      def configure(&block)
        block.bind(config).call
      end
    end
  end

_______________________________________________
Rails-core mailing list
[email protected]
http://lists.rubyonrails.org/mailman/listinfo/rails-core

Reply via email to