Rails: ArgumentError — вы не можете определить уже определенный столбец

У меня есть приложение Rails 6 (6.0.0rc1). У него есть модели книг и авторов, которые имеют ассоциации has_many :through. Я создал таблицу соединений с

rails g migration CreateJoinTableAuthorsBook author:references books:references

Как видите, я неправильно назвал таблицу и неправильно сослался на книгу. Я удалил миграцию и создал новую миграцию

rails g migration CreateJoinTableAuthorsBooks author:references book:references

Теперь, когда я запускаю миграцию, я получаю

ArgumentError: you can't define an already defined column 'author_id'.

Я обыскал все свое приложение Rails, но нигде не могу найти 'author_id'. Я выполнил предыдущую миграцию (с неверными значениями). Как я могу удалить предыдущий 'author_id', чтобы я мог успешно выполнить миграцию?


person hashrocket    schedule 12.07.2019    source источник
comment
Вы уже запускали db:migrate с предыдущей миграцией?   -  person Schwern    schedule 12.07.2019
comment
Да, я выполнил предыдущую миграцию.   -  person hashrocket    schedule 12.07.2019


Ответы (4)


ОБНОВЛЕНИЕ Проблема, скорее всего, связана с новой миграцией. В Rails 5.2 (у меня нет под рукой Rails 6) rails g migration CreateJoinTableAuthorsBooks author:references book:references производит миграцию следующим образом:

create_join_table :authors, :books do |t|
  t.references :author, foreign_key: true
  t.references :book, foreign_key: true
end

create_join_table :authors, :books уже создает таблицу со ссылками (хотя они не объявлены внешними ключами). t.references :author и t.references :book избыточны. В Rails 5.2 эта избыточность упускается из виду, но, возможно, в Rails 6 нет.

По этой причине я бы рекомендовал настроить вашу миграцию, чтобы все было правильно объявлено и проиндексировано.

create_join_table :authors, :books, column_options: { null: false, foreign_key: true } do |t|
  t.index [:author_id, :book_id]
  t.index [:book_id, :author_id]
end

Обычная процедура исправления неправильной миграции – сначала откатить миграцию с помощью rails db:rollback, а затем затем удалить неверный файл миграции. Для отката требуется, чтобы откатываемая миграция все еще существовала (и была обратима).

В противном случае начните с новой базы данных разработки, используя версию db/schema.rb с rails db:reset. Обратите внимание, что это уничтожит ваши базы данных разработки и тестирования; это не должно быть проблемой. Убедитесь, что ваш db/schema.rb не содержит изменений из вашей ошибочной миграции, обычно вы можете убедиться в этом, проверив его из системы контроля версий.

Наконец, если все действительно запутано, включая db/schema.rb, rails db:migrate:reset повторно запустит все ваши миграции, перестроит db/schema.rb заново и предоставит вам свежие базы данных для разработки и тестирования.

person Schwern    schedule 12.07.2019
comment
Когда я запускаю rails db:migrate:reset, я получаю ту же ошибку. Если я запускаю rails db:reset, я получаю You have 1 pending migration: CreateJoinTableAuthorsBooks. - person hashrocket; 12.07.2019
comment
@хэшрокет rake db:drop && rake db:create && rake db:migrate - person engineersmnky; 12.07.2019
comment
@engineersmnky: я пробовал. Все еще получаю ту же ошибку. - person hashrocket; 12.07.2019
comment
@hashrocket Вы уверены, что удалили этот неверный файл миграции? Если да, не могли бы вы показать нам содержание новой миграции? - person Schwern; 12.07.2019
comment
@hashrocket Возможно ли, что author:references book:references избыточен с create_join_table? Это должно быть rails g migration CreateJoinTableAuthorsBooks author book? - person Schwern; 12.07.2019
comment
Вот что я сделал. Я создал новую пустую миграцию с именем CreateJoinTableAuthorsBooks. Я побежал rails db:migrate. Затем я добавил в author:references and book:references. Я сделал быстрый тест, и, похоже, он сработал. Мне нужно было уйти, поэтому я сделаю еще тесты сегодня вечером, когда вернусь домой. - person hashrocket; 12.07.2019

create_join_table :authors, :books 

исправит это для вас, поскольку рельсам 6 не нужны эти объявления.

person milaziggy    schedule 03.12.2019

У меня была такая же проблема при работе над приложением Rails 6.

== 20200711132707 CreateProducts: migrating ===================================
-- create_table(:products)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

you can't define an already defined column 'voltage'.

Вот как я это исправил:

Проблема заключалась в том, что я дважды определил атрибут модели, который в данном случае был voltage:decimal. Поэтому, когда я запускаю rails db:migrate, он выдает ошибку.

Я исправил, сначала удалив файл миграции для продуктов.

А затем повторное создание миграции для продуктов.

На этот раз, когда я запускал rails db:migrate, все работало хорошо.

Это все.

Надеюсь, это поможет

person Promise Preston    schedule 11.07.2020

У меня была такая же проблема, вам больше НЕ нужны ссылки:

# remove these:
t.references :author, foreign_key: true
t.references :book, foreign_key: true

Примечание: вы по-прежнему можете использовать параметры, использованные в t.references, с create_join_table, используя аргумент column_options.

Например:

create_join_table :authors, :books, column_options: { type: :uuid, null: false, index: true, foreign_key: true } do |t|
    ...
end
person Alessandro De Simone    schedule 15.06.2020