我发现其中一个遗留应用程序存在问题(过时的rails-3.0.20)。 此应用程序具有许多组件和嵌套模型。问题仅存在于一个生产服务器上(与其他产品和我的开发人员相同的环境)。
有名称空间的模型看起来像
module Great
class Item
end
end
表名称为great_items
。
当我在有错误的服务器上调试/打开它时,我发现计算的表名是items
而不是great_items
。
$ Great::Item.all
#=> ActiveRecord::StatementInvalid: No attribute named `name` exists for table `items`
所以我认为mby有一个具有相同命名空间的simmilar类,我已经检查了它,但事实并非如此。我的第二个想法是设置表名明确我试过
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'),但上面的错误没有错过。
当我在生产环境中上课时,问题消失了 - 但它不是解决方案。
最后我在reset_column_information
之后使用set_table_name
来解决这个问题,但我认为这也不是一个好方法。
我的问题是你知道究竟是什么导致了这个问题以及如何在不重新加载类缓存的情况下解决它?
答案 0 :(得分:1)
正如您所注意到的,假定的表名不考虑模块。
但正如您所知,您可以使用以下方式自行设置:
self.table_name = 'great_items'
根据this doc,因为你使用3.0.x,你必须使用:
set_table_name "great_items"
这必须放在班级定义之上
答案 1 :(得分: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