このチャプターで達成すること
この「ユーザーモデル開発」では
- ユーザーモデルの作成と
- バリデーションの設定
- バリデーションのテストを行います。
このチャプターを通して、モデル開発の基礎を学びましょう。
今回達成すること
ユーザーテーブル設計を理解します。
ユーザー名の考え方やユーザーの認証設計について学んでいきましょう。
作業的にはユーザーモデルとユーザーテーブルを作成します。
$ rails dbconsole
を使ったテーブルの確認方法についても触れています。
それでは参りましょう。
ユーザーテーブル設計
先に今回作成するユーザーテーブルの設計を確認しておきます。
カラム | 型 | デフォルト | NULL | 長さ | 内容 |
---|---|---|---|---|---|
name | String | false | 30 | ユーザー名 | |
String | false | 255 | メースアドレス | ||
password_digest | String | false | 72 | パスワード | |
activated | Boolean | false | false | メール認証フラグ | |
admin | Boolean | false | false | 管理者フラグ |
-
name
... ユーザー名。これは一意性のアカウント名ではなくニックネーム的な扱いです。
入力必須、30文字制限を付けます。
-
email
.. ユーザーメールアドレス。会員登録、ログインに使用します。
-
password
... ユーザーパスワード。会員登録、ログイン、ユーザー削除などの重要な操作に使用します。
-
activated
... メール認証フラグ。メールが認証されたユーザーは
true
になります。 -
admin
... 管理者フラグ。今回は使用しませんが、管理者だけが行える操作、管理画面の表示切り替えなどに使います。
ユーザー名の考え方
TwitterやQiita、GitHubなどユーザーがコンテンツを不特定多数に公開できるようなWebサービスの場合、ユーザー名を一意性のユーザーIDとして扱った方が良いでしょう。
他のユーザーがIDで検索することができたり、メールアドレスに変えてログインすることができたり、マイページのURLとして利用することができたり。
利便性が高まります。
ただ今回は、プライベートな業務アプリを想定しているため、個人を認識するためだけに使用します。
ユーザー名に一意制約や英数字必須などのバリデーションは設けません。
このように、どんなアプリケーションを作りたいのかでユーザー名の使用目的も変化します。
自分が作りたいサービスに良く似たサービスを見つけ、研究することをおすすめします。
ユーザー認証設計
今回のユーザー認証設計はこの手順になります。
- ユーザーが新規会員登録を行います。
- ユーザーテーブルに
activated: false
の状態で保存されます。 - 登録されたメールアドレスに期限付きの認証用URLを送信します。
- 期限以内に認証用URLをクリックした場合
activated: true
になり、認証を完了します。
- 認証用URLの期限が切れた場合
- ユーザーは1に戻り、もう一度会員登録を行います。
activated: false
の状態のユーザーはテーブルに保存されたままになります。
メールアドレスの一意性
今回のユーザー認証設計の場合、email
カラムに一意制約を付けると期限切れのユーザーは二度と新規会員登録できなくなります。
そこで同じメールアドレスは何度でも保存可能とし、認証済みのユーザーが既に存在する場合は保存不可とします。
これにより認証済みメールアドレスの一意性を保ちます。
ブランチ切っとく
さて、前提知識はこれぐらいにしといて作業に入りましょう。
「api」ディレクトリに移動してブランチを切っておきましょう。
root $ cd api
api $ git checkout -b 20200708_modeling_users
api $ git branch
20200702_initial_settings
* 20200708_modeling_users
master
移動できていることを確認できたら「root」ディレクトリに戻りましょう。
api $ cd ..
ユーザーモデルを作成する
Railsにユーザーモデルを作成します。
$ rails generate model
コマンドを実行しましょう。
root $ docker-compose run --rm api rails g model User --no-fixture
invoke active_record
create db/migrate/20200708014630_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
-
--no-fixture
... fixture(フィクスチャ)ファイルを作成しない。フィクスチャとは、テストデータを作成する用のファイルです。
今回のテストデータは、seedデータから読み込むのでこのファイルは使用しません。
マイグレーションファイルの編集
「db/migrate」ディレクトリ以下の作成されたマイグレーションファイル
api/db/migrate/<作成日時>_create_users.rb
class CreateUsers < ActiveRecord::Migration[6.0]
def change
create_table :users do |t|
# 追加
t.string :name, null: false
t.string :email, null: false
t.string :password_digest, null: false
t.boolean :activated, null: false, default: false
t.boolean :admin, null: false, default: false
# ここまで
t.timestamps
end
end
end
テーブル作成コマンドを実行する
テーブル作成コマンドdb:migrate
を実行しましょう。
root $ docker-compose run --rm api rails db:migrate
# 成功
== 20200708014630 CreateUsers: migrating ======================================
-- create_table(:users)
-> 0.2358s
== 20200708014630 CreateUsers: migrated (0.2361s) =============================
上記のマイグレーションファイルを元にしたユーザーテーブルが作成されます。
マイグレイトに失敗した場合
一から作り直す必要があります。
db:migrate:reset
コマンドを実行してください。
docker-compose run --rm api rails db:migrate:reset
作成されたテーブルを確認してみよう
本当に作成されたのか?
Railsのデータベースコンソールに入って確認してみましょう。
root $ docker-compose run --rm api rails dbconsole
PostgreSQLのパスワードを求められます。
「root」ディレクトリの
Password for user postgres: <PostgreSQLのパスワード> <Enterキー>
このような表示になれば無事入れたということです。
ちなみに「app_development」は現在ログインしているデータベース名になります。
app_development=#
テーブル一覧表示コマンド「\d 」
「app_development」データベースにどんなテーブルがあるのか確認してみましょう。
app_development=# \d
Schema | Name | Type | Owner
--------+----------------------+----------+----------
public | ar_internal_metadata | table | postgres
public | schema_migrations | table | postgres
public | users | table | postgres
public | users_id_seq | sequence | postgres
「users」テーブルが作成されていますね。
その他のテーブルなどはRailsが勝手に作成するものなので気にしなくてOKです。
テーブル構造を確認「\d <テーブル名>」
ユーザーテーブルの中身を確認してみましょう。
app_development=# \d users
Column | Type | Collation | Nullable | Default
-----------------+--------------------------------+-----------+----------+-----------------------------------
id | bigint | | not null | nextval('users_id_seq'::regclass)
name | character varying | | not null |
email | character varying | | not null |
password_digest | character varying | | not null |
activated | boolean | | not null | false
admin | boolean | | not null | false
created_at | timestamp(6) without time zone | | not null |
updated_at | timestamp(6) without time zone | | not null |
Indexes:
"users_pkey" PRIMARY KEY, btree (id)
-
id
... Railsが自動作成してくれるカラム。この
id
がユーザーの**PRIMARY KEY(プライマリーキー)**となります。PRIMARY KEYとは、1つのデータを認識するための重複しない値を言います。
テーブル内の
id
は、データを認識するただ一つの値何ですね。 -
Type
... カラムの型。マイグレーションファイルで指定した型になります。
-
Collation(コレーション)
... 照合順序。データの並び順。マイグレーションファイルに直接SQLを書くことで実現するようです。
しかしRailsの
order
メソッドで並び替えが行えるので、ここは気にする必要はありません。参考 How to specify a collation for a column when creating a model with rails - Stack Overflow
-
Nullable
... NULL制約が表示されます。 -
Default
... デフォルトで入る値が表示されます。
PostgreSQLから抜ける「\q」
マイグレーションファイル通りに作成できていることが確認できました。
それではPostgreSQLから抜けましょう。
app_development=# \q
以上で今回の作業は終了です。
まとめ
今回はユーザーテーブル設計について学び、実際にユーザーテーブルを作成するところまでを行いました。
データベース設計は本当に肝です。
ここを全く考えないで作業を始めるとコードの書き換え、設計のやり直しなど後戻り作業が頻繁に発生します。
ただそうは言ってもデータベース設計は先を読む力、つまり経験値が必要です。
最初は完璧になんて不可能なので、ある程度考え、実装し、間違っていればまたやり直す。を繰り返すことが一番の近道です。
あ、どうせ変化していくものなので完璧を求めすぎないこともポイントですよ。
次回は?
ここ記事で作成したユーザーテーブルにバリデーションをかけていきます。
あと、パスワードの暗号化gem BCrypt(ビークリプト)
の使い方も説明していきますね。
どうぞ、↓下の記事リストへお進みください。