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

时间:2013-08-16 15:33:11

标签: ruby-on-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”,它可以工作。所以问题是如果有办法解决这个问题。

2 个答案:

答案 0 :(得分: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文件的任何显式require语句

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

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

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

答案 1 :(得分:2)

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

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

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

application.rb的{​​{1}}:

config.autoload_path