类名冲突跨模块

时间:2017-02-01 20:05:15

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

我在与类名和模块相关的Rails 4应用程序中遇到了一个问题。

我的主应用程序中有一个继承自Event的{​​{1}}类。我的/ lib目录中还有一组文件,这些文件已分组到我调用ActiveRecord::Base的模块中。该模块中有一个类,它也被命名为LibModule。我注意到引用这些类的一些有趣的东西。以下是使用Rails控制台的一些示例。

示例#1:从未引用Event时,将加载ActiveRecord版本:

Event

示例#2:首先引用LibModule :: Event:

> Event
=> Event(id: integer...)

因此,当我的服务器重新启动(更新后等)时,如果用户参与触发服务器活动的行为,我会偶尔收到以下错误:

> LibModule::Event
=> LibModule::Event
> Event
=> LibModule::Event

我知道有几种方法可以确保这里没有冲突。处理这种情况的最佳做法是什么?

  1. 我尝试使用gems中的类名复制Example#2中的行为,看起来Rails完全隔离了gem中的类。有没有办法在这里做同样的事情?我认为这将是我理想的情况。
  2. 我应该只更改superclass mismatch for class Event 的名称吗?
  3. 我应该确保在初始化期间加载LibModule::Event类吗?
  4. 其他一些我没想过的Rails最佳实践?

3 个答案:

答案 0 :(得分:1)

这与the way qualified constants are resolved by the Rails autoloader有关。该文档提供了以下解决方案:

  

这种命名冲突在实践中很少见,但是如果发生这种冲突,require_dependency通过确保在冲突的地方定义触发启发式所需的常量来提供解决方案。

在您的情况下,解决方案是将其添加到LibModule::Event的类定义之上:

require_dependency 'event'

这将通知自动加载器{(1}}常量引用您的ActiveRecord模型,确保::Event的适当常量命名。

答案 1 :(得分:0)

尽管Ruby中没有任何内容可以阻止您使用重复的类名,但Rails自动加载器很容易被它们搞糊涂,这可能会导致很多问题。

由于这个原因,我通常会尽量避免重复。有时他们工作,有时他们不工作,代码的工作/不工作方面通常取决于采取哪个入口点,哪些事情首先加载,使其无法预测。

您可以尝试通过Event末尾的require_relative强制加载lib_module.rb课程来规避这一点。

答案 2 :(得分:0)

要引用主事件类,请尝试::Event::是范围解析运算符,用于指定全局/主范围。