PG::DependentObjectsStillExist: ERROR: невозможно удалить отчеты таблицы, потому что другие объекты зависят от него
Дать немного фона. Я новичок в Ruby on Rails, и я делаю обзорный веб-сайт, где пользователи могут публиковать отзывы. Я поиграл с "отчетливой" полиморфной ассоциацией, а затем с таблицей отчетов. Позже я удалил таблицу отчетов и создал другую таблицу отчетов. Более ранняя миграция не позволяла создать новую таблицу отчетов о переносе, поэтому я добавил "1" рядом с именем миграции более ранней миграции.
20180311071357_create_reports_1.rb
class CreateReports1 < ActiveRecord::Migration[5.0]
def change
create_table :reports do |t|
t.string :reason
t.text :description
t.string :email
t.belongs_to :reportable, polymorphic: true
t.timestamps
end
end
end
Перенесемся в настоящее время. Некоторое время я не выполнял постановку Heroku, а просто создавал приложение. Когда меня толкают к героку, я получаю следующую ошибку:
heroku run rake db:migrate --trace
Running rake db:migrate --trace on ⬢ housereview... up, run.6689 (Free)
** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
** Invoke db:load_config (first_time)
** Execute db:load_config
** Execute db:migrate
(4.0ms) SELECT pg_try_advisory_lock(2386658352535867725);
ActiveRecord::SchemaMigration Load (4.6ms) SELECT "schema_migrations".* FROM "schema_migrations"
Migrating to DeleteReports1 (20180318091834)
(1.2ms) BEGIN
== 20180318091834 DeleteReports1: migrating ===================================
-- drop_table(:reports)
(2.8ms) DROP TABLE "reports"
(2.6ms) ROLLBACK
(2.3ms) SELECT pg_advisory_unlock(2386658352535867725)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::DependentObjectsStillExist: ERROR: cannot drop table reports because other objects depend on it
DETAIL: constraint fk_rails_cfc8432c20 on table notes depends on table reports
HINT: Use DROP ... CASCADE to drop the dependent objects too.
: DROP TABLE "reports"
...
/app/bin/bundle:3:in `load'
/app/bin/bundle:3:in `<main>'
Caused by:
ActiveRecord::StatementInvalid: PG::DependentObjectsStillExist: ERROR: cannot drop table reports because other objects depend on it
DETAIL: constraint fk_rails_cfc8432c20 on table notes depends on table reports
HINT: Use DROP ... CASCADE to drop the dependent objects too.
: DROP TABLE "reports"
/app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec'
.......
/app/bin/bundle:3:in `load'
/app/bin/bundle:3:in `<main>'
Caused by:
PG::DependentObjectsStillExist: ERROR: cannot drop table reports because other objects depend on it
DETAIL: constraint fk_rails_cfc8432c20 on table notes depends on table reports
HINT: Use DROP ... CASCADE to drop the dependent objects too.
/app/vendor/bundle/ruby/2.3.0/gems/activerecord-5.0.6/lib/active_record/connection_adapters/postgresql/database_statements.rb:98:in `async_exec'
Это моя схема
ActiveRecord::Schema.define(version: 20180407122611) do
create_table "locations", force: :cascade do |t|
t.string "address"
t.string "street_number"
t.string "locality"
t.string "postal_code"
t.string "country"
t.string "route"
t.string "state"
end
create_table "notes", force: :cascade do |t|
t.text "description"
t.integer "report_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["report_id"], name: "index_notes_on_report_id"
end
create_table "reports", force: :cascade do |t|
t.string "reason"
t.text "description"
t.integer "user_id"
t.integer "review_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "completed_at"
t.index ["review_id"], name: "index_reports_on_review_id"
end
create_table "reviews", force: :cascade do |t|
t.string "title"
t.string "duration"
t.text "positive"
t.text "negative"
t.integer "location_id"
t.integer "user_id"
t.integer "rating_safety"
t.integer "rating_neighbour"
t.integer "rating_owner"
t.integer "rating_school"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "rating_overall"
t.boolean "blocked"
t.index ["location_id"], name: "index_reviews_on_location_id"
end
create_table "users", force: :cascade do |t|
t.string "email", default: "", 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.integer "sign_in_count", default: 0, null: false
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
t.string "current_sign_in_ip"
t.string "last_sign_in_ip"
t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
t.string "unconfirmed_email"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "admin", default: false
t.string "first_name"
t.string "last_name"
t.string "locality"
t.string "state"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
Я пытался (почти) все, чтобы исправить проблему. Следующие вещи, которые я до сих пор пробовал - удалили производственное приложение, а затем восстановили pgbackup - удалили производственное приложение, а затем попытались сделать новый 'git push heroku master' и затем 'heroku run rake db:migrate' - Tried drop команду table, а затем снова нажать код и набрать rake db:migrate - Попробовал 'DROP TABLE, если существует каскад отчетов;' в pgsql
Все вышесказанное не повезло. Приложение отлично работает в dev (SQLite), но heroku не позволяет мне рейкить db:migrate.
Заранее спасибо!
2 ответа
Таблица примечаний содержит report_id в качестве внешнего ключа, поэтому вы не смогли удалить таблицу отчетов. Вы можете сделать с помощью dependent: :destroy
В файле report.rb измените строку ниже
has_many :notes
в
has_many :notes, dependent: :destroy
У вас все еще есть миграция, которая создала notes
стол вокруг? Я предполагаю, что create_table :notes
в этой миграции не будет точно соответствовать тому, что вы видите в своем db/schema.rb
,
Неважно, ваша проблема в том, что notes.report_id
Рекомендации reports.id
через внешний ключ внутри базы данных. Этот внешний ключ, вероятно, был создан t.references :report, foreign_key: true
в миграции для обеспечения ссылочной целостности (т.е. база данных будет гарантировать, что любое значение в notes.report_id
ссылается что-то в reports
Таблица). Это ограничение внешнего ключа не позволяет вам сбросить reports
таблица, поскольку это будет нарушать ограничение на notes.report_id
,
Я не думаю, что вы действительно хотите удалить reports
стол вообще. Вместо этого вы хотите сделать reports
стол в Heroku соответствует что schema.rb
говорит. Миграции не должны длиться вечно, поэтому удалите оскорбительные миграции и напишите новую, которая принесет reports
стол в Heroku синхронно с чем schema.rb
говорит.
Как только вы исправите этот беспорядок, вы захотите сделать две вещи:
Никогда не переименовывайте миграции снова. Удалите старые миграции и добавляйте новые время от времени. Если вы хотите сохранить старый, но использовать его имя для чего-то другого, добавьте суффикс к новой миграции, но на самом деле нет никаких причин, чтобы старые миграции оставались там навсегда.
Установите PostgreSQL в вашей локальной среде разработки. Вы всегда должны разрабатывать, тестировать и развертывать с одним и тем же стеком. Между базами данных так много различий, что ActiveRecord не защитит вас от того, что использование разных баз данных в трех средах - это безумие и всего лишь кратчайший путь к боли и страданиям.