首页 > 解决方案 > ActiveRecord::StatementInvalid: PG::UndefinedTable: 错误: 关系“通道”不存在

问题描述

我正在尝试部署到 Heroku,但遇到了 sqlite3 错误,因此我按照https://devcenter.heroku.com/articles/sqlite3 上的说明切换到 postgres,但现在运行 rails 时出现错误分贝:迁移。

我已经尝试删除数据库并使用 rails db:drop db:create 再次创建它,但无法让它工作。

我的迁移:

class CreateRooms < ActiveRecord::Migration[5.2]
  def change
    create_table :rooms do |t|
      t.string :name
      t.text :description
      t.integer :session_id
      t.references :channel, foreign_key: true

      t.timestamps
    end
  end
end

在我的房间模型中:

class Room < ApplicationRecord
  belongs_to :channel
  has_many :users
end

在我的频道模型中:

class Channel < ApplicationRecord
  has_many :rooms, dependent: :destroy
  has_many :registrations, dependent: :destroy
  has_many :users, through: :registrations
end

运行 rails db:migrate 时出现此错误

PG::UndefinedTable: ERROR:  relation "channels" does not exist
: CREATE TABLE "rooms" ("id" bigserial primary key, "name" character varying, "description" text, "session_id" integer, "channel_id" bigint, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_1f9c11d4ad"
FOREIGN KEY ("channel_id")
  REFERENCES "channels" ("id")
)
/CIS-196/final-project/db/migrate/20201128050333_create_rooms.rb:3:in `change'
bin/rails:4:in `<main>'

Caused by:
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR:  relation "channels" does not exist
: CREATE TABLE "rooms" ("id" bigserial primary key, "name" character varying, "description" text, "session_id" integer, "channel_id" bigint, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_1f9c11d4ad"
FOREIGN KEY ("channel_id")
  REFERENCES "channels" ("id")
)
/CIS-196/final-project/db/migrate/20201128050333_create_rooms.rb:3:in `change'
bin/rails:4:in `<main>'

Caused by:
PG::UndefinedTable: ERROR:  relation "channels" does not exist
/CIS-196/final-project/db/migrate/20201128050333_create_rooms.rb:3:in `change'
bin/rails:4:in `<main>'
Tasks: TOP => db:migrate

这是架构:

ActiveRecord::Schema.define(version: 2020_12_12_224511) do

  create_table "active_storage_attachments", force: :cascade do |t|
    t.string "name", null: false
    t.string "record_type", null: false
    t.integer "record_id", null: false
    t.integer "blob_id", null: false
    t.datetime "created_at", null: false
    t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
    t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
  end

  create_table "active_storage_blobs", force: :cascade do |t|
    t.string "key", null: false
    t.string "filename", null: false
    t.string "content_type"
    t.text "metadata"
    t.bigint "byte_size", null: false
    t.string "checksum", null: false
    t.datetime "created_at", null: false
    t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
  end

  create_table "channels", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "registrations", force: :cascade do |t|
    t.integer "channel_id"
    t.integer "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["channel_id"], name: "index_registrations_on_channel_id"
    t.index ["user_id"], name: "index_registrations_on_user_id"
  end

  create_table "rooms", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.integer "channel_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "session_id"
    t.index ["channel_id"], name: "index_rooms_on_channel_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "name"
    t.string "email", default: "", null: false
    t.string "password_hash"
    t.text "bio"
    t.integer "room_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.index ["room_id"], name: "index_users_on_room_id"
  end

end

这些是迁移文件:迁移文件的 屏幕截图

标签: ruby-on-railspostgresqlsqliteherokuheroku-postgres

解决方案


您的房间表引用通道表。因此,您需要在创建房间表之前创建通道表。您需要重命名创建通道表的迁移,以便它出现在创建房间表的迁移之前。

因此重命名20201128050352_create_channels.rb20201128050332_create_channels.rb,使其在之前运行20201128050333_create_rooms.rb。然后运行rails db:drop && rails db:create && rails db:migrate


推荐阅读