具有命名空间的模型 - 表名错误(没有命名空间)

3

我是一名有用的助手,可以为您进行文本翻译。

我在一个旧版应用程序(过时的rails-3.0.20)中发现了一个问题。该应用程序具有许多组件和嵌套模型。问题仅存在于一个生产服务器上(与其他生产环境和我的开发环境相同)。

有一个名称空间的模型看起来像:

module Great
  class Item
  end
end
表名被命名为great_items
。 当我在有故障的服务器上进行调试/打开时,我发现计算出的表名应该是great_itemsitems
,但实际上是。
$ Great::Item.all
#=> ActiveRecord::StatementInvalid: No attribute named `name` exists for table `items`

所以我想也许有相同命名空间的类,我检查了一下,但没有找到。我的第二个想法是明确设置表名,我尝试了一下。

self.table_name = 'great_items'
# &
set_table_name 'great_items'

在这些更改之后,我运行了rails c命令,表名已经成功设置:

$ Great::Item.table_name
#=> 'great_items'

但是当我尝试获取一些物品时,出现了一个奇怪的错误,直到现在我仍然无法理解!
$ Great::Item.all
#=> ActiveRecord::StatementInvalid: Mysql2::Error: Table 'db.items' doesn't exist: SELECT `great_items`.* FROM `items` WHERE `great_items`.`some_default_scope` = 0

如上例所示,表格中的select值和where语句的名称都是正确的,但from的值是不正确的。
我很好奇,因此我检查了ActiveRecord::Base mysql适配器,发现有一种缓存表名的方式,所以我尝试使用reset_table_name。重置后可以设置期望的名称('great_items'),但上述错误仍然存在。
当我在生产环境中关闭类缓存时,问题消失了,但这不是解决方案。
最终,我使用set_table_name之后的reset_column_information来“解决”这个问题,但我认为这也不是一个好的解决方案。
我的问题是,您知道这个问题的真正原因是什么,如何在不重新加载类缓存的情况下解决它?

不行。但我现在检查了一下,结果并不令人满意: irb(main):001:0> Great::Item.table_name_prefix => "great_" irb(main):002:0> Great::Item.table_name => "items" - SZMER
2个回答

2

如您所见,假定的表名不考虑模块。

但是,正如您已经了解的那样,您可以使用以下方式自行设置:

self.table_name = 'great_items'

根据这份文档,因为你使用的是3.0.x版本,所以你需要使用以下代码:
set_table_name "great_items"

这个必须放在你的类定义的顶部。


我写的代码没有成功 - 和 set_table_name & reset_table_name 得到了相同的结果。表名被正确设置,但查询语句却使用了错误的表名。 - SZMER
你确定你添加了 self 吗? - apneadiving
1
如果您在类定义的顶部使用 set_table_name,会发生什么? - apneadiving
我没想到它会有所改变,但它确实起了作用。 - SZMER
我之前尝试过,但在那之前我加载了一些模块,然后尝试了set_table_name。在替换了几行代码之后,一切都正常工作了。 - SZMER
我理解这可能会令人困惑。Ruby代码在运行时执行,因此行的顺序很重要。 - apneadiving

1

试试这个

class RenameOldTableToNewTable< ActiveRecord::Migration
  def self.up
    rename_table :old_table_name, :new_table_name
  end 
  def self.down
    rename_table :new_table_name, :old_table_name
  end
end

不能更改表名,因为这将破坏与其他系统的向后兼容性。此外,在其他服务器上,此代码仅适用于其中一个,该服务器是例外情况 :) - SZMER
你应该按照@apneadiving的建议使用set_table_name。 - Xeeshan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接