Rails迁移创建表时引用模型出现“表不存在”的问题

3
我正在使用rails 5.1.4和mysql2适配器。当我尝试在迁移中创建一个引用另一个表的表时,它会显示“表不存在”。我不明白为什么会出现这个错误。看到不能帮助任何故障排除的错误是没有意义的。
我阅读了另一篇文章(Migration to create table raises Mysql2::Error: Table doesn't exist),所提出的解决方案对我有用。然而,我对这个解决方案有一些担忧,因为它建议用“integer”替换“references”,并在被引用的类名后添加“_id”。这使得数据库不知道FK约束(从日志中执行的mysql可以看出)。
此外,这个错误只发生在少数几个迁移中。其他具有引用的迁移工作正常。
如前所述,解决问题的方法似乎不正确。
失败的迁移代码如下:
class CreateLocatableEntitiesPlaceEntitiesPlaces < ActiveRecord::Migration[5.1]
  def change
    create_table :locatable_entities_place_entities_places do |t|
      t.string :name
      t.integer :type
      t.references :locality, foreign_key: true, index: {:name => "index_places_on_locality_id"} 
      t.references :establishment, foreign_key: true, index: {:name => "index_places_on_establishment_id"} 
      t.references :parking, foreign_key: true, index: {:name => "index_places_on_parking_id"} 
      t.boolean :show_in_map
      t.boolean :show_locality_name
      t.date :constructed_on
      t.integer :total_area
      t.float :lat
      t.float :long

    end
  end
end

还想补充一点,我已经将我的模型命名空间化到子文件夹中,这就是为什么我手动命名索引的原因,因为它们对MySQL来说太大了难以处理。以防万一与此有关。

下面是我的迁移文件夹的截图,其中包含按顺序运行的所有迁移。

Migrations folder of rails app


当我试图创建一个外键到一个主键为int的表时,我遇到了类似的问题。由于Rails 5默认使用bigint来作为主键和外键类型,而不是int,所以我不得不在引用中指定type::integer。我有点惊讶Rails不能自行解决这个问题... - TanguyP
2个回答

2

我意识到我的初始代码存在问题。在迁移中将foreign_key设置为true需要能够发现表格。由于从引用中指定的名称并不明显,因此会出现错误。

在rails 5+中,您可以指定键应引用的表格名称。更改后,我能够顺利运行迁移。

以下是更新后的代码:

class CreateLocatableEntitiesPlaceEntitiesPlaces < ActiveRecord::Migration[5.1]
  def change
    create_table :locatable_entities_place_entities_places do |t|
      t.string :name
      t.integer :type
      t.references :locality, foreign_key: {to_table: :base_entities_locality_entities_localities}, index: {:name => "index_places_on_locality_id"}
      t.references :establishment, foreign_key: {to_table: :locatable_entities_place_entities_establishments}, index: {:name => "index_places_on_establishment_id"} 
      t.references :parking, foreign_key: {to_table: :locatable_entities_place_entities_parkings}, index: {:name => "index_places_on_parking_id"} 
      t.boolean :show_in_map
      t.boolean :show_locality_name
      t.date :constructed_on
      t.integer :total_area
      t.float :lat
      t.float :long

    end
  end
end

如我在问题中提到的那样,我对我的模型进行了命名空间处理,这就是rails无法自行找到表名的明显原因。

这篇文章帮助解决了这个问题:在“references”迁移中指定列名


0

它涉及您迁移 `db/migrate' 文件夹中的文件顺序。

如果包含外键的 `table` 的 `migration-file` 在 `Parent Table` 之前执行,则会抛出 `table not found` 错误。

在您的情况下,应首先迁移以下表格的迁移:
index_places_on_locality , index_places_on_establishment, index_places_on_parking

然后是 CreateLocatableEntitiesPlaceEntitiesPlaces 表。

检查您的 `db/migrate'` 文件夹中的顺序。

迁移文件将以当前日期和时间命名。因此,它将按照该顺序执行。请参阅 Running Migrations


我猜这不是情况。请参考我的问题截图(已编辑),其中迁移按时间戳排序的迁移文件夹。 - VPaul

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