如何创建可配置的Ruby on Rails插件?

时间:2009-06-02 17:40:22

标签: ruby-on-rails ruby plugins ruby-on-rails-plugins

我正在尝试创建我的第一个rails插件,我希望它是可配置的,也就是说,我希望能够在environment.rb文件中设置变量。

更新:我正在尝试做类似于此处所做的事情:http://soakedandsoaped.com/articles/read/exception-notifier-ruby-on-rails-plugin。我试过模仿他们的代码,但我无法让它工作。

我让插件使用硬编码的值,但到目前为止我尝试过的所有内容都无法使用。

以下是一些代码:

#vendor/plugin/markup/lib/markup_helper.rb
module MarkupHelper
    def stylesheet_cache_link_tag(*sources)
      cache = assests_cache_dir ? assests_cache_dir : ""
      options = sources.extract_options!.stringify_keys
      cached_name = options.delete("cached_name")
      stylesheet_link_tag(sources, :cache=> File.join(cache, cached_name))
    end

    def javascript_cache_include_tag(*sources)
      cache = assests_cache_dir ? assests_cache_dir : ""
      options = sources.extract_options!.stringify_keys
      cached_name = options.delete("cached_name")
      javascript_include_tag(sources, :cache=> File.join(cache, cached_name))
    end
end

#something like the following in config/environment.rb or probably config/environments/production.rb
MarkupConfig.assests_cache_dir = "cache"

我希望assests_cache_dir默认为“cache”,但能够在环境配置文件中设置。我已经搜索了很长时间,并且找不到任何讨论这个问题。我怎么能做到这一点?

2 个答案:

答案 0 :(得分:2)

module MarkupHelper
  mattr_accessor :assets_cache_dir
  self.assets_cache_dir = "cache"

  def assets_cache_dir
    MarkupHelper.assets_cache_dir
  end
end

然后在environment.rb(或者development.rb / test.rb / production.rb中,如果你想为每个环境设置不同的值):

MarkupHelper.assets_cache_dir = "my-value"

答案 1 :(得分:1)

尽管tomafro使用的方法非常容易使用,但另一种方法是使用可根据环境拆分的database.yml样式配置文件:

module MyPlugin
  class Configuration
    # == Constants ==========================================================

    CONFIG_FILES = [
      "#{RAILS_ROOT}/config/myplugin.yml",
      "#{RAILS_ROOT}/config/myplugin.yaml"
    ].freeze

    DEFAULT_CONFIGURATION = {
      :url => DEFAULT_HOSTNAME
    }.freeze

    # == Class Methods ======================================================

    # :nodoc:
    def self.config_file_found
      CONFIG_FILES.find do |path|
        File.exist?(path)
      end
    end

    # Returns the default path to the configuration file
    def self.default_path
      config_file_found or CONFIG_FILES.first
    end

    # == Instance Methods ===================================================

    # Creates a new MyPlugin::Configuration instance by reading from the
    # configuration file.
    # +env+ The Rails environment to load
    def initialize(env)
      config_file = self.class.config_file_found

      @env_config = DEFAULT_CONFIGURATION

      if (@config = (config_file and YAML.load(File.open(config_file))))
        [ @config['defaults'], @config[env] ].each do |options|
          if (options)
            @env_config = @env_config.merge(options.symbolize_keys)
          end
        end
      end
    end

    # Will return +true+ if a configuration file was found and loaded, or
    # +false+ otherwise.
    def exists?
      @env_config != DEFAULT_CONFIGURATION
    end

    # Returns a particular configuration option.
    def [](key)
      @env_config[key.to_sym]
    end
  end

  def self.config
    @config ||= Configuration.new(Rails.env)
  end
end

您可以将其用作:

settting = MyPlugin.config[:param_name]

您还可以编写实用程序方法来获取特定值,或使用OpenStruct而不是配置哈希。这仅仅是作为另一种设计模式的一个例子。