0
0

More than 1 year has passed since last update.

railsチュートリアル第六章 ユーザーのモデルを作成する

Posted at

ユーザーのモデルを作成する

新しいユーザーを作成するためのスタブページを作ったところで終わりました
これから6つの章を通して、ユーザー登録ページを作っていくことにしましょう。

本章では、
一番重要なステップであるユーザー用のデータモデルの作成と、
データを保存する手段の確保について学んでいきます。

自分で認証システムを作ってみる

すべてのWebアプリケーションは何らかのログイン/認証システムを必要と
多くのWebフレームワークではこのようなログイン/認証システムを実装するための選択肢が多数提供されています

出来合いのシステムは内部が謎だらけの“ブラックボックス”になっている可能性もあり、
そうしたシステムで使われている複雑怪奇なデータモデルをいきなり用いると初心者はもちろん、
ベテラン開発者すらそうしたモデルに不慣れであれば、途方に暮れてしまうかもしれません。
自分自身で認証システムを構築した経験があれば、サードパーティ製品を理解し、必要に応じて変更することがずっと容易になるはずです。

Userモデル

ここから3つの章にわたる最終目標はユーザー登録ページを作成すること
今のままでは新しいユーザーの情報を受け取っても保存する場所がないので、いきなりページを作成するわけにはいきません。
ユーザー登録でまず初めにやることは、それらの情報を保存するためのデータ構造を作成することです。

Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデル(Model)と呼びます

Railsでは、データを永続化するデフォルトの解決策として、データベースを使ってデータを長期間保存します。

データベースとやりとりをするデフォルトのRailsライブラリはActive Recordと呼ばれます
Active Recordは、データオブジェクトの作成/保存/検索のためのメソッドを持っています。

Railsにはマイグレーション(Migration)という機能があります。
データの定義をRubyで記述することができ、SQLのDDL(Data Definition Language)を新たに学ぶ必要がありません。つまりRailsは、データベースの細部をほぼ完全に隠蔽し、切り離してくれます。

$ git checkout -b modeling-users

データベースの移行

カスタムビルドクラスのUserを思い出してください
このクラスは、nameとemailを属性に持つユーザーオブジェクトでした
Railsにとって極めて重要な部分である永続性という要素が欠けていました。

RailsコンソールでUserクラスのオブジェクトを作っても、コンソールからexitするとそのオブジェクトはすぐに消えてしまいました。
この節での目的は、簡単に消えることのないユーザーのモデルを構築することです。

nameとemailの2つの属性からなるユーザーをモデリングするところから始めましょう。

class User
  attr_accessor :name, :email
  #インスタンス変数の読み取りの確認
  .
  .
  .
end

Railsはデータを保存する際にデフォルトでリレーショナルデータベースを使います。
リレーショナルデータベースは、データ行で構成されるテーブルからなり、各行はデータ属性のカラム(列)を持ちます。
nameやemailといったカラム名を今のうちに考えておくことで、後ほどUserオブジェクトの各属性をActiveRecordに伝えるときに楽になります。

ユーザーコントローラ(とnewアクション)を作ったときに使った次のコマンドを思い出してみてください

$ rails generate controller Users new

モデルを作成するときは、上と似たようなパターンでgenerate modelというコマンドを使います。
今回はnameやemailといった属性を付けたUserモデルを使いたいので、実際に打つコマンドは下

Userモデルを生成する

ubuntu:~/environment/sample_app (modeling-users) $ rails generate model User name:string email:string
Running via Spring preloader in process 4242
      invoke  active_record
      create    db/migrate/#####_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml

コントローラ名には複数形を使い、モデル名には単数形を用いるという慣習を頭に入れておいてください。コントローラはUsersでモデルはUserです。
name:stringやemail:stringオプションのパラメータを渡すことによって、データベースで使いたい2つの属性をRailsに伝えます
これらの属性の型情報も一緒に渡します
アクション名を使って生成した例と比較してみてください。

rails generate controller StaticPages home help

generateコマンドの結果のひとつとして、マイグレーションと呼ばれる新しいファイルが生成されます。
マイグレーションは、データベースの構造をインクリメンタルに変更する手段を提供します。それにより、要求が変更された場合にデータモデルを適合させることができます

マイグレーションはモデル生成スクリプトによって自動的に作られました。リスト 6.2に示したようにnameとemailの2つのカラムを持つusersテーブルを作成します

(usersテーブルを作るための)Userモデルのマイグレーション

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

マイグレーションファイル名の先頭には、それが生成された時間のタイムスタンプが追加されます
マイグレーション自体は、データベースに与える変更を定義したchangeメソッドの集まりです

changeメソッドはcreate_tableというRailsのメソッドを呼び、ユーザーを保存するためのテーブルをデータベースに作成します。

create_tableメソッドはブロック変数を1つ持つブロックを受け取ります。

そのブロックの中でcreate_tableメソッドはtオブジェクトを使って、nameとemailカラムをデータベースに作ります。型はどちらもstringです4 。

ロックの最後の行t.timestampsは特別なコマンドで、created_atupdated_atという2つの「マジックカラム(Magic Columns)」を作成します。

これらは、あるユーザーが作成または更新されたときに、その時刻を自動的に記録するタイムスタンプです

マイグレーションは、次のようにdb:migrateコマンド を使って実行することができます。これを「マイグレーションの適用(migrating up)

$ rails db:migrate

初めてdb:migrateが実行されると、db/development.sqlite3という名前のファイルが生成されます。

演習

1.あなたの環境にあるdb/schema.rbの内容を調べ、その内容とマイグレーションファイル(リスト 6.2)の内容を比べてみてください。

db/schema.rb
# 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: 0) do

end
マイグレーションファイル(リスト 6.2)
class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email

      t.timestamps
    end
  end
end

2つのコードはブロックみたいに見える。

2.ほぼすべてのマイグレーションは、元に戻すことが可能です
元に戻すことを「ロールバック(rollback)と呼び、Railsではdb:rollbackというコマンドで実現できます。

$ rails db:rollback

上のコマンドを実行後、db/schema.rbの内容を調べてみて、ロールバックが成功したかどうか確認してみてください。
上のコマンドでは、データベースからusersテーブルを削除するためにdrop_tableコマンドを内部で呼び出しています。
これがうまくいくのは、drop_tableとcreate_tableがそれぞれ対応していることをchangeメソッドが知っているからです。

buntu:~/environment/sample_app (modeling-users) $ rails t
Running via Spring preloader in process 10489
Migrations are pending. To resolve this issue, run:

        rails db:migrate RAILS_ENV=test
ubuntu:~/environment/sample_app (modeling-users) $ rails db:migrate
== ####### CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0054s
== ####### CreateUsers: migrated (0.0064s) =============================
# 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: #########) do

  create_table "users", 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

変化が起きた。内容はわからない。

ubuntu:~/environment/sample_app (modeling-users) $ rails db:rollback
== ########## CreateUsers: reverting ======================================
-- drop_table(:users)
   -> 0.0062s
== ########## CreateUsers: reverted (0.0132s) =============================
# 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: 0) do

end

元に戻った。

3.もう一度rails db:migrateコマンドを実行し、db/schema.rbの内容が元に戻ったことを確認してください。

ubuntu:~/environment/sample_app (modeling-users) $ rails db:migrate
== ######## CreateUsers: migrating ======================================
-- create_table(:users)
   -> 0.0299s
== ######## CreateUsers: migrated (0.0311s) =============================
# 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: #########) do

  create_table "users", 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

できた。

0
0
0

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