我知道自从第一次提出这个问题以来已经有很长时间了,但我还有一个额外的答案想要分享。
我有几个 Ruby 应用程序是由另一位程序员在几年内开发的,它们在不同的应用程序中重复使用相同的类,尽管它们可能访问同一个数据库。由于这违反了 DRY 规则,我决定创建一个类库以供所有 Ruby 应用程序共享。我本可以将它放在主 Ruby 库中,但这会将自定义代码隐藏在我不想做的公共代码库中。
我遇到了一个问题,我在已经定义的名称“profile.rb”和我正在使用的类之间存在名称冲突。在我尝试创建公共代码库之前,这种冲突不是问题。通常,Ruby 首先搜索应用程序位置,然后转到 $LOAD_PATH 位置。
application_controller.rb 找不到我创建的类,并在原始定义上抛出错误,因为它不是类。由于我从应用程序的 app/models 部分中删除了类定义,Ruby 无法在那里找到它,并在 Ruby 路径中寻找它。
因此,我修改了 $LOAD_PATH 变量以包含我正在使用的库目录的路径。这可以在初始化时在 environment.rb 文件中完成。
即使将新目录添加到搜索路径中,Ruby 也会抛出错误,因为它优先获取系统定义的文件。$LOAD_PATH 变量中的搜索路径优先搜索 Ruby 路径。
因此,我需要更改搜索顺序,以便 Ruby 在搜索内置库之前在我的公共库中找到该类。
这段代码是在 environment.rb 文件中完成的:
Rails::Initializer.run do |config|
* * * * *
path = []
path.concat($LOAD_PATH)
$LOAD_PATH.clear
$LOAD_PATH << 'C:\web\common\lib'
$LOAD_PATH << 'C:\web\common'
$LOAD_PATH.concat(path)
* * * * *
end
我不认为您可以在此级别使用之前给出的任何高级编码结构,但如果您想在应用程序的初始化时设置一些东西,它就可以正常工作。在将原始 $LOAD_PATH 变量添加回新变量时,您必须保持其原始顺序,否则一些主要的 Ruby 类会丢失。
在 application_controller.rb 文件中,我只使用了一个
require 'profile'
require 'etc' #etc
这会加载整个应用程序的自定义库文件,也就是说,我不必在每个控制器中都使用 require 命令。
对我来说,这是我正在寻找的解决方案,我想我会将它添加到这个答案中以传递信息。