LoginSignup
0
0

More than 3 years have passed since last update.

Rails6 usersテーブルにpasswordカラムが作成されなくて困った話

Posted at

目的

  • マイグレーションファイルの記載を間違えてコマンド$ rails db:migrateを実行してしまい、その後記載を正しいものにしてもpasswordカラムが作成されなかった時の解決方などをまとめる。

結論

  • 一旦マイグレーションファイルを削除して再度マイグレーションファイルを作成し記載内容を確かめた上でrails db:migrateを実行した。

困りごとに至った経緯

  1. 自作プロダクトでログイン機能を実装したい。
  2. usersテーブルにはすでにnameカラムとemailカラムと初期設定カラムが作成されていたのでマイグレーションファイルを作成してpasswordカラムの追加を行おうと思った。
  3. コマンド$ rails g migration add_password_to_usersを実行した。作成されたマイグレーションファイル名は「20191211134100_add_password_to_users.rb」である
  4. マイグレーションファイルへの書き込みをしないままコマンド$ rails db:migrateを実行してしまう。
  5. マイグレーションファイルに記載をしていないことが判明、下記の内容を記載するもコードミスをする。(add_columnのnがない)

     class AddPasswordToUsers < ActiveRecord::Migration[6.0]
        def change
          add_colum :users, :password, :string 
        end
     end
    
  6. コードをミスっているマイグレーションファイルをコマンド$ rails db:migrateで反映させてしまう。

  7. マイグレーションファイルのコードミスに気がつき、修正し再度コマンド$ rails db:migrateを実行した。

  8. rails consoleにてusersテーブルのidが1のレコード情報をuserに格納しpasswordカラム情報を追記しようとしたところ下記のエラーが発生した。(passwordカラムなんて存在しないぜという感じのエラー)(エラーコード以外のrails console内での出力は省略)

    irb(main):001:0> user = User.find_by(id:1)
    irb(main):002:0> user.password = "0000"
    Traceback (most recent call last):
            1: from (irb):2
    NoMethodError (undefined method `password=' for #<User:0x00007fd0e2424fe0>)
    

解決までの経緯

  1. 現在のテーブルのカラムがどうなっているか知りたかったのでアプリ名/db/schema.rbを確認しに行った。下記に問題発生時のschema.rbを記載する。

    ActiveRecord::Schema.define(version: 2019_12_14_093144) do
    
      create_table "posts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
        t.text "content"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.decimal "study_time", precision: 10
        t.text "hash_tag"
      end
    
      create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
        t.string "name"
        t.string "email"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
      end
    
    end
    
  2. 前述の結果からusersテーブルにpasswordカラムが存在していないことがわかる。

  3. マイグレーションファイルが空状態やコードミス状態でのコマンド$ rails db:migrateの実行もありなんとなく原因がわかった。

  4. すでに、データベースに反映させたマイグレーションファイルはGit登録してしまっているので当該コミットをrevertするかマイグレーションファイルを作り直して再度コマンド$ rails db:migrateを実行するか迷った。

  5. マイグレーションファイルを再度作成し直してデータベースに反映させることにした。

  6. 下記コマンドを実行して引っ掻き回してしまったマイグレーションファイルを削除する。

    $ rm -rf アプリ名/db/migrate/20191211134100_add_password_to_users.rb
    
  7. 下記コマンドを実行してマイグレーションファイルを再作成した。

    $ rails g migration add_password_to_users
    
  8. 作成されたマイグレーションファイルにミスがない様に記載をした。下記に正しいマイグレーションファイルの内容を記載する。

    class AddPasswordToUsers < ActiveRecord::Migration[6.0]
      def change
        add_column :users, :password, :string 
      end
    end
    
  9. 下記コマンドを実行してマイグレーションファイルの内容をデータベースに反映させた。

    $ rails db:migrate
    >== 20191214093144 AddPasswordToUsers: migrating 
    >===============================
    >-- add_column(:users, :password, :string)
    >-> 0.0144s
    >== 20191214093144 AddPasswordToUsers: migrated (0.0145s) 
    >======================
    
  10. passwordカラムが追加されているか確かめるためアプリ名/db/schema.rbを確認しに行った。下記に問題発生時のschema.rbを記載する。

    ActiveRecord::Schema.define(version: 2019_12_14_093144) do
    
      create_table "posts", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
        t.text "content"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.decimal "study_time", precision: 10
        t.text "hash_tag"
      end
    
      create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
    COLLATE=utf8mb4_0900_ai_ci", force: :cascade do |t|
        t.string "name"
        t.string "email"
        t.datetime "created_at", precision: 6, null: false
        t.datetime "updated_at", precision: 6, null: false
        t.string "password"
      end
    
    end
    
  11. usersテーブル部分にt.string "password"の記載を発見したので無事passwordカラムが追加されていそう。

  12. rails consoleをでusersテーブルのidが1のユーザのpasswordが登録できるか試してみた。(エラーコードは出なかったためrails console内での出力は省略)

    $ cd アプリ名フォルダ
    $ rails console
    irb(main):001:0> user = User.find_by(id:1)
    irb(main):002:0> user.password = "0000"
    irb(main):003:0> user.save
    User Update (0.5ms)  UPDATE `users` SET `users`.`updated_at` = '2019-12-14 09:35:32.920487', `users`.`password` = '0000' WHERE `users`.`id` = 1
       (0.7ms)  COMMIT
    => true
    
  13. 値をデータベースに保存する時にtrueが出たためpasswordカラムが作成され、正常に値も格納されたことを確認できた。

  14. 今回の件にはあまり関係無いが、アプリ名/app/models/user.rbにpasswordカラムの空欄を弾く様にバリデーションを追記した。下記にuser.rbの内容を記載する。

    class User < ApplicationRecord
        validates :email, {presence: true, uniqueness: true}
        validates :name, {presence: true}
        validates :password, {presence: true}
    end
    
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0