У меня есть модель User
и модель Role
. Когда я начал создавать приложение, я начал с создания модели User
, а созданный файл миграции содержит ссылку на роли:
class CreateUsers < ActiveRecord::Migration[5.0]
def change
create_table :users do |t|
t.string :first_name
t.string :last_name
t.string :username
t.string :email
t.string :password
t.string :password_digest
t.boolean :banned
t.references :role, foreign_key: true
t.timestamps
end
end
end
Затем я создал модель Role
, которая сгенерировала этот файл миграции:
class CreateRoles < ActiveRecord::Migration[5.0]
def change
create_table :roles do |t|
t.string :title
t.integer :access_level
t.timestamps
end
end
end
Я пытаюсь выполнить развертывание в Heroku и перенести свою базу данных в соответствии с документацией, используя следующую команду heroku run rails db:migrate
(используя Rails 5).
Я получаю сообщение об ошибке от Heroku:
heroku run rake db:migrate
Running rake db:migrate on ⬢ gentle-headland-79177... up, run.9293 (Free)
D, [2016-12-31T08:15:33.131367 #4] DEBUG -- : (90.7ms) CREATE TABLE "schema_migrations" ("version" character varying PRIMARY KEY)
D, [2016-12-31T08:15:33.152682 #4] DEBUG -- : (11.5ms) CREATE TABLE "ar_internal_metadata" ("key" character varying PRIMARY KEY, "value" character varying, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL)
D, [2016-12-31T08:15:33.155373 #4] DEBUG -- : (1.1ms) SELECT pg_try_advisory_lock(6845940114126317925);
D, [2016-12-31T08:15:33.172106 #4] DEBUG -- : ActiveRecord::SchemaMigration Load (1.2ms) SELECT "schema_migrations".* FROM "schema_migrations"
I, [2016-12-31T08:15:33.178453 #4] INFO -- : Migrating to CreateUsers (20161117083901)
D, [2016-12-31T08:15:33.181903 #4] DEBUG -- : (0.9ms) BEGIN
== 20161117083901 CreateUsers: migrating ======================================
-- create_table(:users)
D, [2016-12-31T08:15:33.199351 #4] DEBUG -- : (13.4ms) CREATE TABLE "users" ("id" serial primary key, "first_name" character varying, "last_name" character varying, "username" character varying, "email" character varying, "password" character varying, "password_digest" character varying, "banned" boolean, "role_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_642f17018b"
FOREIGN KEY ("role_id")
REFERENCES "roles" ("id")
)
D, [2016-12-31T08:15:33.200707 #4] DEBUG -- : (1.0ms) ROLLBACK
D, [2016-12-31T08:15:33.202190 #4] DEBUG -- : (1.2ms) SELECT pg_advisory_unlock(6845940114126317925)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::UndefinedTable: ERROR: relation "roles" does not exist
: CREATE TABLE "users" ("id" serial primary key, "first_name" character varying, "last_name" character varying, "username" character varying, "email" character varying, "password" character varying, "password_digest" character varying, "banned" boolean, "role_id" integer, "created_at" timestamp NOT NULL, "updated_at" timestamp NOT NULL, CONSTRAINT "fk_rails_642f17018b"
FOREIGN KEY ("role_id")
REFERENCES "roles" ("id")
)
Насколько я понимаю, Heroku ожидает, что сначала будет определено Role
, а затем User
.
Почему на моей локальной машине я могу выполнить db:migrate нормально, но на Heroku это не удается?
Возможно, разница между Sqlite3 и Postgresql?
Как решить эту проблему развертывания?
Мне просто переименовать мой файл миграции create_role, чтобы он имел более раннюю отметку времени, чем файл миграции create_user? Это даже рекомендуемая практика? :D
Обновлять
Я сделал git-клон своего репозитория в папку на рабочем столе на своем iMac.
Затем я запустил rails db:migrate
на этой новой локальной копии.
Никакой ошибки. Все миграции БД выполнены, все таблицы на месте вместе со всеми отношениями. Что-то действительно не так на конце Heroku.
Обновление 2
Сделал еще одну проверку моего репозитория в новую папку на рабочем столе, запустил bundle install
, а затем попробовал эту версию команды db: migrate:
rails db:migrate RAILS_ENV=production
и я вижу тот же вывод ошибки о ролях не существует
ТЕМ НЕ МЕНИЕ
Затем я создал новый проект рельсов honey
:
rails new honey
Сделал bundle install
Затем пошел:
rails generate model User name:string role:references
Наконец я пошел:
rails db:migrate RAILS_ENV=production
и ошибок нет...
Я явно не сгенерировал никакую модель Role
, так почему же она не дает сбоев?
Вот лог консоли:
Warlocks-iMac:bad clementwu$ cd honey/
Warlocks-iMac:honey clementwu$ ls
Gemfile Rakefile config lib test
Gemfile.lock app config.ru log tmp
README.md bin db public vendor
Warlocks-iMac:honey clementwu$ rails generate model User name:string role:references
Running via Spring preloader in process 27200
Expected string default value for '--jbuilder'; got true (boolean)
invoke active_record
create db/migrate/20170101100613_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
Warlocks-iMac:honey clementwu$ rails db:migrate RAILS_ENV=production
== 20170101100613 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.0018s
== 20170101100613 CreateUsers: migrated (0.0018s) =============================
Warlocks-iMac:honey clementwu$
База данных создана и даже показывает внешний ключ role_id
, несмотря на отсутствие таблицы с именем role
в моей производственной базе данных:
Сбивает с толку :D
Обновление 3
Возможно, это разница между базой данных sqlite3 и базой данных postgresql.
По умолчанию приложение rails config/database.yml
указывает, что производственная база данных называется db/production.sqlite3
, т. е. она не использует базу данных PostgreSQL, поэтому она не выдает ошибку о том, что роли не существуют.
И согласно этому сообщению Stackoverflow: Поддерживает ли SQLite ссылочную целостность?
Похоже, что SQLite3 не гарантирует ссылочную целостность :(
Сильная боль в ягодицах.
Хорошо, что это только личный проект обучения, а не рабочий проект.
Также нереально начинать с PostgreSQL, вы не можете просто удалить и воссоздать базу данных так же легко, как с SQLite3 и Rails CLI.
Я предполагаю, что урок, который нужно усвоить здесь, заключается в том, чтобы хорошенько подумать и сначала создать зависимые таблицы.
User
) не существует. Я думаю проблема кроется где-то глубже. Поэтому, основываясь на этом результате, я не думаю, что переименование файла миграции — это правильный путь. - person Zhang   schedule 31.12.2016