带有命名空间的模型 - 错误的 table 名称(没有命名空间)

Model with namespace - wrong table name (without namespace)

我发现其中一个遗留应用程序(已过时 rails-3.0.20)存在问题。 这个应用程序有很多组件和嵌套模型。问题只存在于其中一台生产服务器上(与其他生产和我的开发环境相同的环境)。

有一个名为 space 的模型看起来像

module Great
  class Item
  end
end

Table 名字被命名为 great_items.

当我 debug/open 它在服务器上出现故障时,我发现计算出的 table 名称是 items 而不是 great_items.

$ Great::Item.all
#=> ActiveRecord::StatementInvalid: No attribute named `name` exists for table `items`

所以我认为 mby 有同名的类似 classspace,我已经检查过了,但不是。我的第二个想法是设置 table name explicit 我试过

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

更改后 运行 rails c 和 table 名称设置正确:

$ 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

正如您在上面的示例中看到的那样,table 在 select 值和 where 语句中具有正确的名称,但在 from 中值不正确。

我很好奇,所以我检查了 ActiveRecord::Base mysql 适配器,发现有一些吸引人的 table 名称,所以我尝试 reset_table_name。重置有助于设置预期的名称('great_items'),但不会遗漏上述错误。

当我在生产环境中打开 class 捕获时问题消失了 - 但它不是解决方案。

最后我有点 'solved' 在 set_table_name 之后使用 reset_column_information,但我认为这也不是好的解决方案。

我的问题是您是否知道真正导致此问题的原因以及如何在不重新加载 class 缓存的情况下解决它?

假定 table 名称没有考虑模块,如您所见。

但如您所知,您可以自己设置,使用:

self.table_name = 'great_items'

根据this doc,因为你使用3.0.x,你必须使用:

set_table_name "great_items"

这必须放在您的 class 定义之上

试试这个

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