【发布时间】:2015-04-10 09:56:55
【问题描述】:
我在为我的 Rails 应用程序构建 ruby gem 时遇到了类重新加载问题。
背景
在 gem 中,我定义了以下类
module MyGem
class AppConfigBase
def app_title
"Title Missing"
end
end
end
在 Rails 应用程序中,我创建了一个 config/my_gem.rb 文件来保存一些特定于应用程序的覆盖。 (我的目标是让 gem 的用户定义一些信息,但在超类中提供一些默认值。)
module MyGem
class AppConfig < AppConfigBase
def app_title
"Great App"
end
end
end
在 gem 内部的某个时刻,我调用 MyGem::AppConfig.new.app_title 并收到正确的字符串。耶!
接下来,我决定稍微挑战一下:我想让自动加载工作,这样开发人员就不必在每次更改此文件时都重新启动 rails 服务器。
我首先尝试查看 Rails 是否已经设置为执行此操作。我从AppConfig 类中删除了app_title 方法。当我重新加载页面时,我仍然得到返回的“Great App”字符串。 :( Rails 没有重新加载config/my_gem.rb(或配置目录中的任何内容),所以这是预期的结果。
接下来,我尝试添加以下初始化程序:
if Rails.env.development?
ActionDispatch::Callbacks.after do
load "#{Rails.root}/config/my_gem.rb"
end
end
上述初始化程序部分解决了问题,但我想了解为什么它不能完全解决问题。有了这个初始化器,
- 如果我从子类中删除
app_title方法,我仍然会得到错误的字符串(子类方法中的那个...不应该再存在了)。 - 如果我重新启动服务器,我会得到预期的字符串的超类版本。
- 现在,如果在子类中重新添加方法并调用 app_title,我会得到字符串的子类版本!
所以当我添加一个方法时,初始化程序中的加载调用似乎会拾取新方法。但是,如果我删除一个方法,它似乎没有帮助。
- 为什么会这样?
- 如何使该文件在更改时自动重新加载? (我看到的最简单的解决方法是将 my_gem.rb 移动到
config/my_gem/my_gem.rb,然后将config/my_gem添加到 Rails 中的自动加载路径中,但我不想创建这个额外的目录只是为了自动加载一些东西。)
【问题讨论】:
标签: ruby-on-rails ruby ruby-on-rails-4