在开发模式下重新加载Rails 3初始化器

6
我正在构建一个 Rails 3 应用程序,用户可以选择多个模板之一来构建一个简单的网站。当应用程序启动时,我正在尝试初始化所有可用的模板。这本质上是一个文件,让我定义它们所有,然后对于每个模板调用 Template.add(template),它会将它们存储在 @@templates 中,并且我可以通过 Template.find(name)访问它们。
问题是,在开发模式下,使调用 Template.add 的初始化器在第一次请求时被加载,然后在 reload!上被清除。我已经阅读了有关 config.to_prepare 的文章,但它对我不起作用,可能是因为我是这样要求模板的:
# template config at app/templates/template_name/template_name.rb
path = File.expand_path(Rails.root + 'app/templates')
Dir[File.join(path, '/*')].each do |template|
  name = File.basename(template)
  require File.join(path, name, "#{name}.rb")
end

我应该怎么做才能在reload!之后重新加载这些文件,或者根本不让它们被删除?如果你有更好的处理方法,请告诉我。我在Rails方面还有很多需要学习的地方,特别是配置方面。

目前我通过在类中加载数据来临时避免这个问题。请帮我摆脱这种丑陋、非模块化的麻烦。


我不确定我理解你的问题。所以我的建议是:为什么不自动加载你的文件?http://hemju.com/2010/09/22/rails-3-quicktip-autoload-lib-directory-including-all-subdirectories/ - apneadiving
不熟悉这个过程,但它无论如何都不能解决我的问题。模板模型在每个请求上重新加载(在开发中cache_classes = false),而我的模板文件不会重新加载,因此在第二个请求中没有任何与模板模型“注册”的模板。 - coreyward
你能详细解释一下为什么你认为使用to_prepare无法正常工作吗? - johnmcaliley
这可能值得一看,因为它详细介绍了初始化过程:http://guides.rubyonrails.org/initialization.html - johnmcaliley
当我使用to_prepare时,所有内容都在第一次运行时加载,然后之后就不再加载了。我想这是因为我使用的是require而不是load - coreyward
2个回答

1

如果您将对Template.add的调用从template_name.rb文件(我假设它们现在在那里)移动到加载代码中,在require之后,我认为您应该能够使用config.to_prepare来完成此操作。例如,考虑向您的Template类添加此类方法,然后甚至在其首次加载时从类本身调用它:

class Template
  def self.load_all
    # template config at app/templates/template_name/template_name.rb
    path = File.expand_path(Rails.root + 'app/templates')
    Dir[File.join(path, '/*')].each do |template|
      name = File.basename(template)
      require File.join(path, name, "#{name}.rb")

      # Register the template even if the class itself is already loaded.
      Template.add(name)
    end
  end

  # Initially load all templates.
  Template.load_all
end

然后从注册自己的template_name.rb文件中删除Template.add(name)代码。(我再次假设这是当前发生的地方 - 我不是很清楚您原始帖子中的信息。)或者,您可能只想确保Template.add具有幂等性并且会静默丢弃重复项。

最后,在config/environments/development.rb中添加以下内容:

config.to_prepare do
  Template.load_all
end

Template类重新加载后,这将重新加载您的所有模板。

我没有尝试过这个,但是在Template类末尾调用Template.load_all,您甚至可能不需要config.to_prepare部分。


我在遇到这个问题时不知道config.to_prepare,自从发布后也没有多想过,但我认为这对我来说会非常有效。等我有时间了试一下,如果可以的话就接受它。 - coreyward

1
如何将模板名称与其文件的查找存储在内存存储器(如memcached或Redis)或甚至数据库中?初始化程序可以加载内存存储器或确保数据库更新所有值,然后Template.find只需查看存储器以查看文件在哪里,或者如果它们已经被加载,则只需获取类名。简单地查看类名是否已定义可以告诉您是否需要要求模板文件或直接创建新实例。
基本上,将@@templates存储在Rails进程内存之外,或者至少存储足够的信息,以便您可以动态构建所需的@@templates部分。

嗯,我绝对不想毫无必要地引入任何额外的依赖项到应用程序中。我曾经使用过ActiveRecord,但我不喜欢在应用程序启动时更改数据库的想法;我觉得如果两个dynos(我在Heroku上)同时启动,可能会出现问题。 - coreyward

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接