【问题标题】:How do I lookup conflicting classes in Rails?如何在 Rails 中查找冲突的类?
【发布时间】:2011-12-01 21:24:07
【问题描述】:

我在一个项目中使用 Rails 3.1,bundler 添加了很多我不太了解的 gem。

由于某种原因在开发模式下(可能是因为它不断卸载类),我间歇性地遇到 ActiveRecord::AssociationTypeMismatch。看起来像这样:

Character(#31360520) expected, got Character(#23815500)

我相信其中一个 gem 定义了一个类“Character”,它与我的 ActiveRecord“Character”模型相冲突。我在搜索这个问题的根源时遇到了麻烦,因为它提供了一堆通用结果,而且我不确定 Ruby 社区对这些数字的称呼是什么(类 ID?)。

有几个问题我很乐意帮助您:

  1. 类名后面括号中的数字是多少?
  2. 如何根据异常中报告的 id 查找该类的来源(在哪个 gem 中)?
  3. 对于通常命名的 ActiveRecord 模型,这里的最佳实践是什么?我应该为我的模型命名空间,还是更多地归咎于 gem 的作者?

【问题讨论】:

  • 要快速测试其中一个 gem 中是否定义了另一个 Character 类,请将您的重命名为 MyCharacter 并查看 Character 是否仍然可用。
  • 在这种情况下整个应用程序肯定无法加载,不是吗?
  • 是的,我尝试用 MyCharacter 替换 Character,但在控制台中找不到 Character。不过它可能仍然是一个命名空间类。

标签: ruby-on-rails ruby-on-rails-3 activerecord bundler


【解决方案1】:

我是个菜鸟,所以不要将我所说的一切都视为既定事实 - 但我认为我可能会有所帮助。

问题 1

不确定,但我怀疑这些数字是预期班级的object_ids。在 ruby​​ 中,类也是对象(尽管是单例对象),因此它们与任何其他对象一样具有 object_id(您可以在任何对象上调用 object_id 以获取其唯一 ID)。如果您想获取环境中加载的每个类的哈希及其 id,您可以在控制台中尝试这样的操作:

    all_classes = ObjectSpace.each_object.select {|o| o.class == Class}
    with_ids    = Hash[ all_classes.map {|c| [c,c.object_id] } ]

问题 2

在控制台中,所有类都显示了它们的完整命名空间路径,因此如果它们属于不同的命名空间,您应该能够使用上述脚本区分您的两个 Character 类。 但是,如果名称空间相同,则问题可能会变得很棘手,因为您的一个类定义将覆盖另一个,具体取决于加载顺序。如果在你的 shell 中使用 ri 可以帮助你找到这种情况下的罪魁祸首,我不会感到惊讶。

问题 3

我会说:避免为您的模型使用模糊、过于常见的名称;但在这种情况下,我会说 gem 是罪魁祸首,因为提供 gem 的人应该非常小心不要污染命名空间,特别是如果它污染了 ActiveRecord::Base 命名空间。

【讨论】:

    猜你喜欢
    • 2020-02-03
    • 2014-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    • 2016-10-29
    • 1970-01-01
    • 2012-05-24
    • 1970-01-01
    相关资源
    最近更新 更多