【问题标题】:Rails: Same name for a library module and a group of controllers?Rails:库模块和一组控制器的名称相同?
【发布时间】:2023-03-22 18:00:02
【问题描述】:

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

【问题讨论】:

  • 你试过::PagerDuty.new()而不是Admin::PagerDuty.new()吗?仅PagerDuty.new() 怎么样?
  • 我得到“未初始化的常量 PagerDuty”
  • 也许我只需要重命名它......对吧?
  • 不,我不这么认为,一定有办法让它发挥作用。如果没有,那将是一件坏事,你不能在 Helper & Lib 中拥有相同的结构并将它们组合起来......

标签: ruby-on-rails


【解决方案1】:

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

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

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

在application.rb 中为config.autoload_path:

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

【讨论】:

  • 是的,它有效!非常令人困惑,抱歉,#{Rails.root} 是区分大小写的。
  • 如果你使用 Windows 运行你的应用程序,你应该使用Rails.root.join('lib', 'admin', 'pagerduty.rb')(它会根据操作系统处理斜杠/反斜杠)@Newbie
  • 我们不在 Windows 机器上。将进行更多测试。
  • 顺便说一句,每次我更改任何代码时,我现在都需要重新启动 Rails 服务器。不像以前我只在更改 Lib 中的代码时才重新启动
  • 希望这个链接有帮助:williambharding.com/blog/rails/…
【解决方案2】:

要在 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。

  • 对于已经定义或在多个位置定义的类(例如猴子补丁),自动加载将不起作用。更多信息here

【讨论】:

  • 当然。类名没问题。
  • 顺便说一句,每次我更改任何代码时,我现在都需要重新启动 Rails 服务器。不像以前我只在更改 Lib 中的代码时才重新启动
  • 是的,我曾经在更改 lib 文件夹时重新启动服务器,这完全没问题,但现在每当我更改任何控制器中的任何内容时!很奇怪。
  • 我认为您在文件和模型/控制器的命名方面可能存在一些不一致之处。这可能会破坏应用程序类的自动加载。你真的在 admin/admin_main.rb 中有控制器代码吗?它应该是 admin/admin_main_controller.rb。那肯定不行。然后控制器名称是 Admin::AdminMainController,对吧?
猜你喜欢
  • 1970-01-01
  • 2017-05-18
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 2017-03-08
  • 1970-01-01
  • 2020-04-04
  • 2012-11-04
相关资源
最近更新 更多