Rails:库模块和一组控制器的名称相同吗?

我正在组织我的代码,到目前为止,我已经成功地将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”,它可以工作。 所以问题是如果有办法解决这个问题。

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

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

另一个解决方案,虽然有点重,但是要加载LOAD_PATH中的所有lib子目录,例如:

config.autoload_path application.rb中:

 config.autoload_paths += Dir["#{config.root}/lib/**/"] 

在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文件的任何显式require语句

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

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

  • 自动加载不适用于已定义或在多个位置定义的类(例如monkeypatches)。 更多信息在这里