4

我正在组织我的代码,到目前为止,我已经成功地controllers/helpers/views在文件夹“admin”中分组,但我曾经有一个具有相同模块名称“admin”的库,我无法调用了。(名称冲突?)

新结构:

Directory Structure
  -> app
    -> controllers 
      -> admin #new
        -> admin_main
        -> admin_permissions

    -> Helpers
      -> admin #new
        -> admin_main_helper
        -> admin_permissions_helper

  -> lib
    -> admin
      -> pagerduty.rb

我曾经可以像这样从我的助手那里调用我的库:

module Admin::AdminMainHelper #admin:: is new
  require "./lib/admin/pagerduty.rb"

  def pager_duty
    pagerduty = Admin::PagerDuty.new() #throws error after the new structure
    @on_call = pagerduty.first_on_call()
    @counts = pagerduty.open_incidents()
  end

end

错误是"uninitialized constant Admin::PagerDuty"

我是否必须将我的库重命名为其他名称?还是有办法解决这个问题?

编辑:例如,如果我将库模块重命名为“AdminLib”而不是“Admin”,它会起作用。所以问题是是否有办法解决这个问题。

4

2 回答 2

4

要在 Ruby 中以正确的方式要求依赖项,您应该:

  • 改名pagerduty.rb => pager_duty.rb
  • 要求它:require 'admin/pager_duty'

这是可能的,因为 Rails 已经在 LOAD_PATH 上添加了 lib 文件夹。这将在生产中很好地完成代码(就像库通常一样)。

但是,如果您希望在开发中开发您的 lib 文件 - 无需在每次进行修改时重新启动服务器,您可以像这样更改您的设置:

  • 将此行添加给您config/application.rb

    config.autoload_paths += %W(#{config.root}/lib)

  • 删除控制器或模型(任何 app/* 文件)内 lib 文件的任何显式要求语句

这也会很好用。但它是一种常见的反模式。因为:

  • lib 代码应该完全独立于您的应用程序,以便您可以在应用程序之间共享它。如果您使用自动加载机制,则意味着它是您的应用程序的一等公民。在这种情况下,最好在应用程序(例如应用程序/工具)中设置一个新文件夹并为其设置自动加载。否则,您最终可能会得到一个杂乱无章的 lib 文件夹,其中充满了依赖于应用程序的代码。更多信息在这里

  • 自动加载不适用于已经定义或在多个地方定义的类(例如猴子补丁)。更多信息在这里

于 2013-08-16T16:27:20.027 回答
2

我认为问题在于加载路径。我认为require应该是:

require "#{Rails.root}/lib/admin/pagerduty.rb"

另一个解决方案,尽管有点笨拙,是加载 中的所有lib子目录LOAD_PATH,例如:

在:application.rb_config.autoload_path

config.autoload_paths += Dir["#{config.root}/lib/**/"]
于 2013-08-16T15:56:05.117 回答