プログラミング備忘録

プログラミングの学習状況をメモしています

44日目

今日の学習

Ruby

Ruby on Rails

Railsチュートリアル 第6章

railstutorial.jp

Userモデルを作成するところまできた。ここでは、データモデルの作成、データを保存する手段を学習していく。

モデル

Railsチュートリアルから重要そうな箇所を抜粋。

  • Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデルと呼ぶ。
  • データベースを使ってデータを長期間保存する。
  • データベースとやりとりをするデフォルトのRailsライブラリのことをActive Recordと呼ぶ。
    Active Record固有のメソッドがある。
  • マイグレーション機能は、データの定義をRubyで記述することができる機能のこと。

モデル(M)は、データベースにアクセスをして、コントローラ(C)からの命令通りに動く役割がある。

モデルを作成するときは、rails g modelで作成をする。作成する際に、オプションパラメータ(name:stringのようなもの)を渡すことで、データベースで使いたいデータをあらかじめRailsに伝えることが出来る。

モデル名には単数形を用いる習慣がある。反対に、コントローラ名は複数形を用いること。

例:model User controller Users

modelをコマンドで作成すると、マイグレーションファイルが作成される。

マイグレーション周りへの理解がまだ乏しいため、改めてマイグレーションとは何かを検索してみる。

Rails初心者がつまずきやすい「マイグレーション」

SQLを書くことなくRubyでデータベース内にテーブルを作成することができる機能」

Active RecordRubySQLに自動翻訳してくれるため、それを利用してデータベースを操作するのがマイグレーション機能のようだ。

rails db:migrateコマンドを実行すると、作成されたマイグレーションファイルを実行してくれて、ファイル内に書かれているRubyの文章をSQLにしてデータベースを操作してくれる。

通常は、テーブルを新規作成したり、カラムを追加したりする際はSQL文を直接実行しなければならないが、マイグレーション機能のおかげで、その都度SQLを発行してくれる。データを追加する際に、柔軟に対応してくれる。

SQL文を書かなくても、Rubyの書き方で指示をすれば自動で色々とやってくれる優れものな機能ということでいいだろうか。

マイグレーションファイルとスキーマファイルについて – Ruby on Rails 始めました

こちらの記事の書き方が分かりやすかったので引用。

マイグレーションファイルというのは、テーブルを作成するための設計図みたいなものです。マイグレーションファイルを実行することで初めてテーブルが作られます。

マイグレーション

rails g model User name:string email:stringを実行して作成された、以下のファイル。

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メソッドは、create_tableメソッドを呼び出して、Userを保存するためのテーブルをデータベースに作成する役割を持つ。

create_tableメソッドは、受け取ったデータ(上の場合はnameとemail)をカラムとしてデータベースに作成する。stringのように、型が指定されていればそれも一緒に登録してくれる。

t.timestampsでは、created_atupdated_atというマジックカラムを作成する。ユーザの作成時、更新時に時刻を自動的に記録してくれる。

また、idカラムも自動で追加されるため、Userのデータモデルは[id], [name], [email], [created_at], [updated_at]の五つのカラムを持つことになる。

rails db:migrate

マイグレーションファイルを、rails db:migrateコマンドで実行して、新しいデータモデルを作成する。

このコマンドでは、/db/migrateディレクトリにあるマイグレーションファイルの中から、未実行のファイルを見つけて実行してくれる。

コマンドを実行して、元に戻したいと思った場合は以下のコマンドを実行することで、一つ前の状態に戻せる。

rails db:rollback

最初の状態に戻したいときは、以下のコマンドを実行する。

rails db:migrate VERSION=0

スキーマ

マイグレーションファイルを実行したことにより、schema.rbがdbディレクトリに自動で作成される。

先程のマイグレーションファイルを実行した場合、以下のようなschema.rbが作成される。

ActiveRecord::Schema.define(version: 2021_06_15_115749) 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

これは、現在のデータベースの構造を記録してあるファイルで、先程作成したカラムが追加されていることが分かる。

schema.rbファイルでは、マイグレーションファイルの実行有無を確認することができる。マイグレーションを実行すると、schema_migrationsテーブルにデータが保存される。

このファイルは、常に最新の状態に自動更新される。試しにrails db:rollbackをしてみると、マイグレーション実行前の、なにもない状態に変化した。

modelファイル

/app/modelに、モデル用のrbファイルが作成される。

rails g model Userで生成されたUserモデル

class User < ApplicationRecord
end

UserクラスにApplicationRecordというクラスが継承されているため、ActiveRecord:Baseクラスのすべての機能が使えるようになっている。

Railsコンソールで、user = User.newで生成したオブジェクトのスーパークラスを見てみると、そのことが分かる。

>> user.class.superclass
=> ApplicationRecord(abstract)
>> user.class.superclass.superclass
=> ActiveRecord::Base
>> user.class.superclass.superclass.superclass
=> Object

バリデーション

バリデーション(検証の意)は、Active Recordの機能であり、モデルの属性値に何らかの制約を与えることができる。

validatesメソッドに特定の引数を与える。

例: validates :name, presence: true

この例の、presence: trueという引数は、要素が一つのオプションハッシュ。ハッシュであるが、最後の引数のため{ }が省略できる。

よく使用されるバリデーション
  • presence(存在性)
    渡された属性が存在するかどうかを検証する。

  • length(文字列の長さ)
    :maximumパラメータを用いると長さの上限を強制できる
    validates :name, length: { maximum: 15 }

バリデーションのテスト

/test/models/〇〇_test.rbを利用して、バリデーションが機能しているのかどうか確かめることができる。

require 'test_helper'

class UserTest < ActiveSupport::TestCase

  def setup
    @user = User.new(name: "Example User", email: "user@example.com")
  end

end

まずはuserの情報を取得できるようにしておき、下に検証したい要素を追加していく。

例えば、presenceのバリデーションがちゃんと機能しているのかどうかを確かめる場合。

test "name should be present" do
  @user.name = "     "
  assert_not @user.valid?
end

文字列の上限を50としているデータに対して、長さの検証をする場合。

test "name should not be too long" do
  # 上限を超えた51文字を代入
  @user.name = "a" * 51
  assert_not @user.valid?
end

valid?メソッドを使用して、@user変数が有効かどうかをチェックできる。

バリデーションが多数ある場合は、すべてのバリデーションに通った場合にtrueを返す。

有効でないオブジェクトはデータベースに保存しようとすると、自動的に失敗になる。

共通のバリデーションを一括で設定

with_optionsを使うと、共通のバリデーションをまとめて設定できることを知った。

validates :name, presence: true
validates :email, presence: true
validates :password, presence: true

このように、presence: trueの設定項目が共通しているものは、with_optionsで一括設定できる。

with_options presence: true do
  validates :name
  validates :email
  validates :password
end

with_optionsを使って、同じバリデーションを一括りにしちゃえ! - Qiita

普段から、「これはもっと簡略化できないだろうか...」と考えながら見ていくことが大事だなと感じた。

学習メモ