教材の内容に関係のない質問や教材とは異なる環境・バージョンで進めている場合のエラーなど、教材に関係しない質問は推奨していないため回答できない場合がございます。
その場合、teratailなどの外部サイトを利用して質問することをおすすめします。教材の誤字脱字や追記・改善の要望は「文章の間違いや改善点の指摘」からお願いします。
アカウントを作成するには、以下の4つの情報が必要です。
Deviseでは、デフォルトでメールアドレスとパスワードのカラムは作成してくれます。なので本パートでは、名前と性別のカラムを追加します。
usersテーブルに名前と性別のカラムを追加します。
では、進めていきましょう。
usersテーブルの構成は以下のようになります。
カラム名 | データ型 |
---|---|
string | |
password | string |
name | string |
gender | integer |
名前をname
、性別をgender
というカラム名にしました。
名前には文字列を格納するためstring
、性別は、enum
を使って0か1の値を格納するため、integer
にしています。
※ enum に関しては後に説明します
新しくカラムを追加する際はマイグレーションファイルを作成します。マイグレーションファイルを作成するには以下のようなコマンドを実行します。
【例】
console Copied!rails g migration クラス名 カラム名:型
参考)Active Record マイグレーション - マイグレーションを作成する
今回は以下のコマンドを実行してマイグレーションファイルを作成してください。
console Copied!rails g migration AddNameAndGenderToUser name:string gender:integer
実行結果は以下になります。
console Copied!rails g migration AddNameAndGenderToUser name:string gender:integer
Running via Spring preloader in process 43596
invoke active_record
create db/migrate/20201117082945_add_name_and_gender_to_user.rb
作成したマイグレーションファイルのカラムにNOT NULL制約とデフォルト値を追加します。NOT NULL制約とは、カラムに格納する値としてNULLを禁止にします。
ユーザーを新規作成するときに、ユーザー名や性別の値が何も入っていないと困るので、name
カラム・gender
カラムにはNOT NULL制約を追加します。
また、gender
カラムには、デフォルト値0
を追加します。この0が何を指しているかは、enum
を解説する際に説明します。
db/migrate
ディレクトリ内にある、xxxxxx_add_name_and_gender_to_user.rb
ファイルを以下のように編集してください。(xxxxxxにはマイグレーションファイルを作成した日時が入ります)
db/migrate/xxxxxx_add_name_and_gender_to_user.rb12345678 Copied!class AddNameAndGenderToUser < ActiveRecord::Migration[6.0]
def change
# ==========ここから編集する==========
add_column :users, :name, :string, null: false
add_column :users, :gender, :integer, null: false, default: 0
# ==========ここまで編集する==========
end
end
マイグレーションファイルを作成しただけでは、テーブルに反映されません。マイグレーションファイルをテーブルに反映するにはマイグレーションファイルを実行する必要があります。以下のコマンドで実行できます。
console Copied!rails db:migrate
上記のコマンドを実行すると下記のような実行結果が表示されます。
console Copied!rails db:migrate
== 20201117082945 AddNameAndGenderToUser: migrating ===========================
-- add_column(:users, :name, :string, {:null=>false})
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
PG::NotNullViolation: ERROR: column "name" of relation "users" contains null values
/Users/daijiro.maeyama/test_projects4/techpit-match/db/migrate/20201117082945_add_name_and_gender_to_user.rb:3:in `change'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/rails:9:in `<top (required)>'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: column "name" of relation "users" contains null values
/Users/daijiro.maeyama/test_projects4/techpit-match/db/migrate/20201117082945_add_name_and_gender_to_user.rb:3:in `change'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/rails:9:in `<top (required)>'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
PG::NotNullViolation: ERROR: column "name" of relation "users" contains null values
/Users/daijiro.maeyama/test_projects4/techpit-match/db/migrate/20201117082945_add_name_and_gender_to_user.rb:3:in `change'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/rails:9:in `<top (required)>'
/Users/daijiro.maeyama/test_projects4/techpit-match/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
実行結果に、StandardError: An error has occurred, this and all later migrations canceled:
とあるようにマイグレーションファイルの実行に失敗しています。
もう少し実行結果を見てみると、PG::NotNullViolation: ERROR: column "name" of relation "users" contains null values
とあります。
これは、「usersテーブルにname
カラムがnull
のレコードがあるよ」というエラーになります。
「4-3 ユーザーの新規登録ができるか確認」のパートを進める際に、nameカラムがない状態でユーザーの新規登録をしたため、上記のようなエラーが出ました。
なので、usersテーブルのレコードを削除しましょう。まずrails console
コマンドを実行してください。
console Copied!rails console
Running via Spring preloader in process 45466
Loading development environment (Rails 6.0.3.4)
irb(main):001:0>
実行したら、User.destroy_all
を実行して、usersテーブルのレコードを全て削除します。
console Copied!irb(main):002:0> User.destroy_all
User Load (2.9ms) SELECT "users".* FROM "users"
(0.1ms) BEGIN
User Destroy (5.3ms) DELETE FROM "users" WHERE "users"."id" = $1 [["id", 1]]
(1.9ms) COMMIT
=> [#<User id: 1, email: "test@gmail.com", created_at: "2020-11-17 07:46:46", updated_at: "2020-11-17 07:46:46">]
モデル名.destroy_all
で、テーブル内の全てのレコードを削除します。
これで、nameカラムがnullのレコードを削除することができました。
もう一度rails db:migration
コマンドを実行してマイグレーションファイルを実行しましょう。
console Copied!rails db:migrate
実行結果は以下になります。
console Copied!rails db:migrate
== 20201117082945 AddNameAndGenderToUser: migrating ===========================
-- add_column(:users, :name, :string, {:null=>false})
-> 0.0097s
-- add_column(:users, :gender, :integer, {:null=>false, :default=>0})
-> 0.0045s
== 20201117082945 AddNameAndGenderToUser: migrated (0.0144s) ==================
これで、name
カラムとgender
カラムを追加できました。
Railsで作成したテーブルの情報は、db/schema.rb
というファイルに記載されています。実際に見てみましょう。
db/schema.rb1234567891011121314151617181920212223242526272829303132 Copied!# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `rails
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_11_17_082945) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "users", force: :cascade do |t|
t.string "email", default: "", null: false
t.string "encrypted_password", default: "", null: false
t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
t.datetime "created_at", precision: 6, null: false
t.datetime "updated_at", precision: 6, null: false
t.string "name", null: false
t.integer "gender", default: 0, null: false
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end
end
現在は、usersテーブルの情報がschema.rb
に記載されています。テーブルやカラムを追加すると、schema.rb
の内容も更新されます。マイグレーションファイルを実行した際はschema.rb
を見て、本当にカラムやテーブルが作成されたか確認するくせをつけましょう。
以上で、本パートは終了です。
お疲れさまでした。