如何在Rails中查找冲突的类?

时间:2011-12-01 21:24:07

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

我在一个项目中使用Rails 3.1,并且捆绑包添加了很多我不太了解其内容的宝石。

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

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

我相信其中一个宝石定义了一个“Character”类,它与我的ActiveRecord“Character”模型相冲突。我在查找这个问题的根源时遇到了麻烦,因为它提出了一堆通用结果,我不确定这些数字是由Ruby社区调用的(类ID?)。

所以我喜欢的一些问题有助于:

  1. 班级名称后的parens中的那个号码是什么?
  2. 如何根据异常中报告的ID查找该类所在的位置(在哪个gem中)?
  3. 这里通常命名为ActiveRecord模型的最佳做法是什么?我应该为我的模型命名,还是对宝石的作者负责?

1 个答案:

答案 0 :(得分:0)

我有点像菜鸟,所以不要认为我所说的一切都是确凿的事实 - 但我想我可能会帮忙。

问题1

不确定,但我怀疑这些数字是预期类别的object_id个。在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

我想说:避免模型的模糊,太常见的名字;但在这种情况下,我会说宝石应该受到责备,因为提供宝石的人应该非常小心,不要污染命名空间,特别是如果它污染了ActiveRecord::Base命名空间。