ruby-on-rails - 如何防止我的初始化程序配置在开发模式中丢失?

标签 ruby-on-rails ruby-on-rails-3.1

我正在开发一个使用引擎的 Rails 应用程序。我正在使用初始化程序来配置我的引擎 Controller 之一,以便它将触发主机应用程序中的操作。代码看起来像这样:

# config/initializers/my_engine.rb
MyEngine::SomeController.after_filter proc {
  # Do something in the host app
}, :only => :update

这在生产中运行良好,但在开发模式下,proc 仅在第一个请求时调用。这是因为类正在重新加载并且此配置丢失,因为它存储在类变量中。 (例如,MyEngine::SomeController 是从它所在的文件中重新加载的,并且由于 after_filter 没有在那里声明,所以它不会重新添加。)

一些 Rails 背景

在开发模式下,Rails 使用以下加载策略:
  • app 中的代码假设您正在积极更改目录,则每次请求都会重新加载目录。
  • lib 中的代码目录,以及 config/initializer文件,已加载 一次 ,当应用程序启动时。

  • 初始化文件通常用于配置 gems。过去,gem 的代码大多位于 lib目录,因此运行一次配置就足够了。

    引擎如何改变事物

    然而,Rails 引擎在 app 中有代码。目录: Controller 、模型等。这些文件在每次请求时以开发模式重新加载。因此,像我上面的示例这样的配置丢失了。

    输入 to_prepare

    Rails 提供 config.to_prepare专门解决这个问题:它在生产中运行一次,并在开发中的每个请求上运行。

    例如,我们在 application.rb 中有这个,它工作正常:
    config.to_prepare do
      # set up class variables (after_filters, etc)
    end
    

    但是,如果我必须将所有引擎的配置放入 application.rb ,这违背了 config/initializers 的观点使事情井井有条。

    因此,对于我的引擎中的任何类配置 app目录,我想将该代码放在 config/initializers 下的文件中.

    这是我的问题。
  • 我不清楚如何获得 config进入初始化文件的范围。我想应该是 Rails.application.config .是对的吗?
  • 我可以添加添加多个to_prepare block ?恐怕多次调用它会覆盖以前的 block 。

  • 更新

    正如@Frederick Cheung 所说,Rails.application.config.to_prepareconfig/initializer 中工作文件,并且可以在各种文件中根据需要使用尽可能多的这些文件;每个调用都将其 block 附加到一个数组中,因此不会覆盖任何内容。

    所以这个问题的解决方案是:
    # config/initializers/my_engine.rb
    Rails.application.config.to_prepare do
      MyEngine::SomeController.after_filter proc {
        # Do something in the host app
      }, :only => :update
    end
    

    一件看起来仍然很奇怪的事情:我预计 to_prepare要在 上调用的 block 每个请求 在开发模式下,但似乎每隔 3 次左右随机调用一次。我添加了 block :
    Rails.application.config.to_prepare do
      Rails.logger.info "Running the prepare block!"
    end
    

    ...重新启动我的应用程序,并刷新页面九次。我只在第 1 次、第 5 次、第 7 次和第 9 次请求中看到了消息。我不确定是什么解释了这种行为,但它确实解释了为什么我的代码 没有 to_prepare在开发中间歇性地工作。

    最佳答案

    没有什么可以阻止您在 app/models 中的文件中执行初始化代码。

    例如

    class MyClass
      def self.run_me_when_the_class_is_loaded
      end
    end
    
    MyClass.run_me_when_the_class_is_loaded
    

    MyClass.run_me... 将在加载类时运行 .... 这是我们想要的,对吧?

    不确定它是否是 Rails 的方式......但它非常简单,并且不依赖于 Rails 的风向。

    关于ruby-on-rails - 如何防止我的初始化程序配置在开发模式中丢失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8895103/

    相关文章:

    ruby-on-rails - ActionDispatch::Cookies 没有跨域设置

    ruby - NoMethodError:#<RSpec::Core::ExampleGroup::Nested_4:0xa05d2a0> 的未定义方法 `belong_to'

    ruby-on-rails-3 - 为什么即使使用 use_transactional_fixtures = false after_commit 也不运行

    ruby-on-rails - 在Rails中使用SimpleRSS解析提要,出现数字代码,无法正确编码

    android - 对于使用移动应用程序的 Sorcery gem,我应该使用什么身份验证方法?

    ruby-on-rails - 如何捕获 ActiveRecord 表的审计历史

    ruby-on-rails - Ruby on Rails 自定义域

    ruby-on-rails - 禁用 rake 数据库 :test:prepare while using cucumber rails

    ruby-on-rails - 在 Rails 中从/public 目录提供字体的缺点是什么?

    html - rails -nokogiri GEM : Detect MIME type of image in URL