【问题标题】:Model with namespace - wrong table name (without namespace)具有命名空间的模型 - 错误的表名(没有命名空间)
【发布时间】:2015-04-29 07:01:52
【问题描述】:

我在一个遗留应用程序(过时的 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 存在具有相同命名空间的类似类,我已经检查过它并没有。我的第二个想法是明确设置表名我试过

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"

标签: mysql ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

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

但正如您已经知道的那样,您可以自己设置,使用:

self.table_name = 'great_items'

根据this doc,因为你用的是3.0.x,所以必须用:

set_table_name "great_items"

这必须放在你的类定义之上

【讨论】:

  • 我写了它没有成功 - 结果与set_table_name & reset_table_name 相同。表名设置正确,但使用错误的表名构建查询。
  • 你确定你确实添加了self
  • 好的,如果您在类定义之上使用set_table_name 会怎样?
  • 我没想到它会改变一些东西,但它成功了。
  • 我之前尝试过,但在它之前我加载了一些模块,然后尝试set_table_name。更换线路后,一切都开始工作了。
【解决方案2】:

试试这个

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

【讨论】:

  • 无法更改表名,因为它会破坏与其他系统的向后兼容性。此外,在其他服务器上,此代码仅适用于其中一个异常:)
  • 那么你应该使用 @apneadiving 所建议的 set_table_name
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
  • 2013-06-17
  • 2011-08-23
  • 1970-01-01
相关资源
最近更新 更多