web-dev-qa-db-ja.com

Railsテーブルに列を追加する移行を作成すると、rake db:migrateの実行時にエラーが発生します

「users」というモデルを作成し、usersテーブルにいくつかの列を追加する新しい移行を作成しました。 rake db:migrateを実行すると、b/cの下にエラーが表示され、usersテーブルを再度作成しようとしています

$ 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

[〜#〜] edit [〜#〜]

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
22
Catfish

Railsは、データベースの「schema_migrations」テーブルで移行を追跡します。 Devise移行である「20120511224920」のエントリがない限り、すでに存在するように見えるので、再度実行しようとします。

その場合は、手動でテーブルに追加できます。

11
omarvelous

エラーは、元のDeviseCreateUsers移行を再度実行しようとしているが、ユーザーテーブルが既に存在するために実行できないことを示しています。

これを修正するには、DeviseCreateUsersのダウン移行を実行してから、通常どおり移行を実行します。あなたはそれをすることができます:

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

20121031XXXXXXXXは、移行名の日付スタンプです。つまり、20120410214815_devise_create_users.rbという名前の移行があり、ファイル名から日付スタンプをコピーしてコマンドに貼り付けます。 参照用Rails移行ガイド です。

編集:これはコメントに記載されていますが、単なる警告の言葉です。テーブルのダウンマイグレーションを実行すると、テーブルにあるエントリが失われます。開発モードで実行しているため、これは問題になりません。実稼働環境にいる場合は、追加の手順を実行してテーブルデータをバックアップし、後でそれを再ロードする必要があります。

6
GorrillaMcD

新しいデータベースを作成してから、もう一度移行してみてください:

rake db:drop:all
rake db:create:all
rake db:migrate
5
Thanh

だから私がこれから集めたものから:

  • 既にユーザーモデルがあります
  • 本番環境にこのバージョンがあります
  • デフォルトのRails generate devise:installを実行しました
  • 次に、Rails_ devise Userを生成して実行しました

私はそれを望んでいます:

  • ソース管理を使用します
  • コードをたくさんチェックする

注:そうでない場合は、なぜそうする必要があるのか​​を学習しようとしています。

Deviseを生成する前にコードを戻す

Deviseを生成する直前に、ポイントの新しいサンドボックスを作成できることを願っています。そうでない場合は、プロジェクトディレクトリをコピーして、手動で実行します。他の唯一のオプションは、Deviseが生成したすべてのファイルを手動で編集することです。

デバイス生成を再実行

  • gemfileにgem 'devise'を追加
  • Railsはdevise:installを生成します
  • Railsはdevise MODELを生成します

モデルが存在しないことを確認してください!あなたがあなたが現在抱えている問題に陥らないなら。

現在のユーザーをあるモデルから別のモデルに移行する

古いユーザーモデルから新しいユーザーモデルに認証情報を完全に移動するためのスクリプトを生成できれば、便利です。現在の認証にDeviseとは異なるハッシュアルゴリズムを使用している場合、すべてのパスワードを無効にし、ユーザーにメールの確認コードORを使用して新しいパスワードを作成するよう要求しますログイン時にユーザーを移行する可能性があります。最初の方法は、クリーンで完全、無礼です。 2番目の方法は、く、不完全で、静かです。好きな方法を選択してください。

編集:おそらく、代わりにアルゴリズムを使用するようにDeviseをカスタマイズする方法を見つけることができます。それはおそらくもっと良いでしょうが、もう少し作業が多く、かなりもろいです。

もう1つのことは、認証モデルがアカウントデータで過負荷にならないことです。アカウントについて追跡したいものを保存するアカウントデータモデルを持つhas_a認証のみを処理するモデルが必要です。

2
Michael McGuire

upメソッドとdownメソッドを使用します。ロールバックや特定の移行ファイルの実行に役立ちます。

構文に従ってください。

  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 = version number #version numberは、移行するバージョンです。

2
vijikumar

移行のバージョンに予期しない値を提供している可能性のある環境変数を確認します。既存の新しい移行を適用する代わりに、db:migrateがテーブルを破壊していた 古い質問 がStack Overflowで見つかりました(そして、それが古くなっている場合は許してください)。

彼らは最終的に、環境変数によってdb:migraterake db:migrate:downと機能的に同等のバージョンパラメータ「0」で実行されることを発見しました。

以前の移行DeviseCreateUsersを含めるか一致させるために、バージョンが予期せず変更されたことが原因である可能性がありますか?

1
lutze

Rails generate devise userいつかDeviseCreateUsersを生成しました。既にユーザーモデルとユーザーテーブルを作成している場合は、生成された移行ファイルをdb/migrateから削除できます。

1
Yanhao

そして、いくつかのダーティな移行を手動で行う必要がある場合:

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

A.new.migrate(:up)
0
Dorian

ちょうど試して

最初のファイルで

create_table(:users), :force => true do |t|

これは他のテーブルをオーバーライドします

0

あなたが言ったことによると、このコマンドを使用して新しい移行を作成しました

$ Rails移行の生成AddDetailsToUsers home_phone:decimal cell_phone:decimal work_phone:decimal birthday:date home_address:text work_address:text position:string company:string

タイプミスかどうかはわかりませんが、「Users」ではなく「AddDetailsToUser」にする必要があります。もう一度確認してください。サポートいたします。これは、生成されたモデルを考案するためのものです。ユーザーに言及すると、dbでユーザーを探します。

Ruby on Rails follow the linguistic Convention.table_nameはPluralですが、model_nameはSingularです。使用するコマンドでmodel_nameを使用する必要があります。

Table_nameを使用する場合は、これを使用します

Rails gの移行add_details_to_users home_phone:decimal ...... etc

0
Nikhil Nanjappa