44日目
今日の学習
Ruby
Ruby on Rails
Railsチュートリアル 第6章
Userモデルを作成するところまできた。ここでは、データモデル
の作成、データを保存する手段を学習していく。
モデル
- Railsでは、データモデルとして扱うデフォルトのデータ構造のことを
モデル
と呼ぶ。 データベース
を使ってデータを長期間保存する。- データベースとやりとりをするデフォルトのRailsライブラリのことを
Active Record
と呼ぶ。
Active Record
固有のメソッドがある。 マイグレーション
機能は、データの定義をRubyで記述することができる機能のこと。
モデル(M)は、データベースにアクセスをして、コントローラ(C)からの命令通りに動く役割がある。
モデルを作成するときは、rails g model
で作成をする。作成する際に、オプションパラメータ(name:stringのようなもの)を渡すことで、データベースで使いたいデータをあらかじめRailsに伝えることが出来る。
モデル名には単数形を用いる習慣がある。反対に、コントローラ名は複数形を用いること。
例:model User
controller Users
modelをコマンドで作成すると、マイグレーション
ファイルが作成される。
マイグレーション周りへの理解がまだ乏しいため、改めてマイグレーションとは何かを検索してみる。
Active Record
がRubyをSQLに自動翻訳してくれるため、それを利用してデータベースを操作するのがマイグレーション機能のようだ。
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_at
とupdated_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
普段から、「これはもっと簡略化できないだろうか...」と考えながら見ていくことが大事だなと感じた。