ruby on rails миграции Rails, создающие миграцию для добавления столбцов в таблицу, вызывают ошибку при запуске rake db: migrate




ruby on rails generate migration add column (8)

У меня есть созданная модель под названием «пользователи», и я создал новую миграцию, чтобы добавить несколько столбцов в таблицу пользователей. Теперь, когда я запускаю rake db: migrate, я получаю ошибку ниже b / c, она пытается создать таблицу пользователей снова

$ rake db:migrate
==  DeviseCreateUsers: migrating ==============================================
-- create_table(:users)
rake aborted!
An error has occurred, all later migrations canceled:

Mysql::Error: Table 'users' already exists: CREATE TABLE `users`.....

Почему он пытается создать таблицу снова?

Вот команда, которую я использовал для создания новой миграции

$ rails generate migration AddDetailsToUsers home_phone:decimal cell_phone:decimal work_phone:decimal birthday:date home_address:text work_address:text position:string company:string

Новая миграция выглядит так:

class AddDetailsToUsers < ActiveRecord::Migration
  def change
    add_column :users, :home_phone, :decimal
    add_column :users, :cell_phone, :decimal
    add_column :users, :work_phone, :decimal
    add_column :users, :birthday, :date
    add_column :users, :home_address, :text
    add_column :users, :work_address, :text
    add_column :users, :position, :string
    add_column :users, :company, :string
  end
end

РЕДАКТИРОВАТЬ

20120511224920_devise_create_users

class DeviseCreateUsers < ActiveRecord::Migration
  def change
    create_table(:users) do |t|
      ## Database authenticatable
      t.string :email,              :null => false, :default => ""
      t.string :username,           :null => false, :default => ""
      t.string :encrypted_password, :null => false, :default => ""

      ## Recoverable
      t.string   :reset_password_token
      t.datetime :reset_password_sent_at

      ## Rememberable
      t.datetime :remember_created_at

      ## Trackable
      t.integer  :sign_in_count, :default => 0
      t.datetime :current_sign_in_at
      t.datetime :last_sign_in_at
      t.string   :current_sign_in_ip
      t.string   :last_sign_in_ip

      ## Encryptable
      # t.string :password_salt

      ## Confirmable
      # t.string   :confirmation_token
      # t.datetime :confirmed_at
      # t.datetime :confirmation_sent_at
      # t.string   :unconfirmed_email # Only if using reconfirmable

      ## Lockable
      # t.integer  :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
      # t.string   :unlock_token # Only if unlock strategy is :email or :both
      # t.datetime :locked_at

      ## Token authenticatable
      # t.string :authentication_token


      t.timestamps
    end

    add_index :users, :email,                :unique => true
    add_index :users, :reset_password_token, :unique => true
    # add_index :users, :confirmation_token,   :unique => true
    # add_index :users, :unlock_token,         :unique => true
    # add_index :users, :authentication_token, :unique => true
  end
end

20120619023856_add_name_to_users

class AddNameToUsers < ActiveRecord::Migration
  def change
    add_column :users, :first_name, :string
    add_column :users, :last_name, :string
  end
end

20121031174720_add_details_to_users.rb

class AddDetailsToUsers < ActiveRecord::Migration
  def change
    add_column :users, :home_phone, :decimal
    add_column :users, :cell_phone, :decimal
    add_column :users, :work_phone, :decimal
    add_column :users, :birthday, :date
    add_column :users, :home_address, :text
    add_column :users, :work_address, :text
    add_column :users, :position, :string
    add_column :users, :company, :string
  end
end

Ошибка говорит о том, что он пытается запустить исходную миграцию DeviseCreateUsers снова и не может, потому что таблица пользователей уже существует.

Чтобы это исправить, вы можете запустить миграцию вниз для DeviseCreateUsers а затем запустить миграцию как обычно. Вы можете сделать это с:

rake db:migrate:down VERSION=20121031XXXXXXXX
rake db:migrate

Где 20121031XXXXXXXX - 20121031XXXXXXXX даты имени миграции. Другими словами, у вас будет миграция с именем 20120410214815_devise_create_users.rb и вы скопируете 20120410214815_devise_create_users.rb даты из имени файла и вставите ее в команду. Вот справочник Rails по миграции .

Редактировать: это отмечено в комментариях, но только слово предупреждения. Запуск миграции вниз для таблицы приведет к потере всех записей в этой таблице. Я предполагаю, что вы работаете в режиме разработки, так что это не должно быть проблемой. Если вы работаете, вам нужно будет предпринять дополнительные шаги для резервного копирования данных таблицы и их последующей перезагрузки, в противном случае у вас будет плохой день (или, может быть, неделя).


использовать методы вверх и вниз. Это будет полезно для отката и запуска конкретного файла миграции.

Пожалуйста, следуйте синтаксису ..

  class AddDetailsToUsers < ActiveRecord::Migration
    def self.up
      add_column :users, :home_phone, :decimal
      add_column :users, :cell_phone, :decimal
      add_column :users, :work_phone, :decimal
      add_column :users, :birthday, :date
      add_column :users, :home_address, :text
      add_column :users, :work_address, :text
      add_column :users, :position, :string
      add_column :users, :company, :string
   end

   def self.down
      remove_column :users, :home_phone
      remove_column :users, :cell_phone
      remove_column :users, :work_phone
      remove_column :users, :birthday
      remove_column :users, :home_address
      remove_column :users, :work_address
      remove_column :users, :position
      remove_column :users, :company
   end
  end


    In this case please try to migrate using version number.

Как и rake db: migrate: down VERSION = номер версии # номер версии - это версия, которую вы хотите перенести.


Можете ли вы попробовать создать новую базу данных, а затем перенести ее снова:

rake db:drop:all
rake db:create:all
rake db:migrate

Rails отслеживает миграции в таблице "schema_migrations" вашей базы данных. Если не существует записи для «20120511224920», которая является миграцией Devise, она попытается запустить ее снова, которая, по-видимому, уже существует.

Вы можете добавить это вручную в таблицу, если это так.


Итак, из чего я взял это:

  • У вас уже была модель пользователя
  • У вас есть версия этого в производстве
  • Вы запустили рельсы по умолчанию генерировать устройство: установить
  • Затем вы запустили рельсы для создания устройства

Я надеюсь, что:

  • Вы используете контроль источников
  • Вы проверяете код много

ПРИМЕЧАНИЕ: если нет, вы собираетесь узнать, почему вам нужно это сделать.

Восстановите код до того, как вы сгенерировали Devise

Надеюсь, вы можете просто создать новую песочницу для точки прямо перед генерацией Devise. Если нет, скопируйте каталог проекта и сделайте это вручную. Единственный другой вариант - вручную отредактировать все файлы, созданные Devise.

Перезапустите свое поколение Devise

  • прочитайте gem 'devise' в ваш Gemfile
  • рельсы создают устройство: установить
  • рельсы создают устройство МОДЕЛЬ

Убедитесь, что эта модель не существует! Если нет, вы попадаете в проблему, которая у вас сейчас есть.

Миграция текущих пользователей из одной модели в другую

Если вы можете сгенерировать сценарий для полного перемещения аутентификационной информации из вашей старой модели пользователя в новую, то это хорошо для вас. Если вы используете другой алгоритм хеширования от Devise для текущей аутентификации, то вы либо аннулируете все свои пароли, и потребуете от своих пользователей создать новый пароль, используя код подтверждения в их электронной почте, ИЛИ вы можете перенести пользователей при входе в систему. в. Первый метод является чистым, полным и грубым. Второй метод уродлив, неполон и молчалив. Выберите свой метод, как вам нравится.

Изменить: Возможно, вы могли бы найти способ настроить Devise для использования вашего алгоритма. Это, вероятно, было бы даже лучше, но немного больше работы и довольно хрупкие.

Другое дело, что ваша модель аутентификации не должна быть перегружена данными учетной записи. У вас должна быть модель, которая обрабатывает только аутентификацию, которая имеет модель данных учетной записи, которая хранит все, что вы хотите отслеживать в отношении учетных записей.


Согласно тому, что вы сказали, вы использовали эту команду для создания новой миграции

$ rails генерирует миграцию AddDetailsToUsers home_phone: десятичное число cell_phone: десятичное число work_phone: десятичное число день рождения: дата home_address: текст work_address: текстовая позиция: строка компания: строка

Я не уверен, если это просто опечатка, но это должно быть "AddDetailsToUser", а не "Пользователи". Просто проверьте еще раз, и мы сможем вам помочь. Это для разработки сгенерированной модели. Когда вы упоминаете пользователя, в БД он ищет пользователей.

Ruby on Rails следует лингвистическому соглашению. Имя_таблицы - множественное число, а имя модели - единственное. Вы должны использовать имя_модели в используемой вами команде.

Если вы хотите использовать table_name, используйте это

рельсы и миграция add_details_to_users home_phone: десятичный ...... и т. д.


Проверьте наличие переменных среды, которые могут указывать неожиданное значение для версии вашей миграции. Я нашел старый вопрос о переполнении стека (и простите меня, если он устарел), где db:migrate уничтожает таблицу, а не применяет существующую новую миграцию.

В конце концов они обнаружили, что переменная окружения заставляла db:migrate работать с параметром версии "0", который функционально эквивалентен rake db:migrate:down

Возможно ли, что ваша ситуация может быть вызвана неожиданным изменением версии для включения или совпадения с предыдущей миграцией DeviseCreateUsers ?


И если вам нужно сделать некоторые грязные миграции вручную:

class A < ActiveRecord::Migration
  def up
    add_column :images, :name
  end
end

A.new.migrate(:up)




migration