1.MVCのmodelの役割
Model:実際に(表示や入力に関連しない)データの処理を行う
View:Modelの状態を表示する
Controller:ModelとViewに処理をお願いする
つまりモデルは、
「データの検索、変換、検証、関連」の処理を担当する部門です。
2.Active Recordについて
Active Recordとは、MVCで言うところのM、つまりモデルに相当するものであり、ビジネスデータとビジネスロジックを表すシステムの階層です。Active Recordは、データベースに恒久的に保存される必要のあるビジネスオブジェクトの作成と利用を円滑に行なえるようにします。Active Recordは、ORMシステムに記述されている「Active Recordパターン」を実装したものであり、このパターンと同じ名前が付けられています。
特に重要な項目は、以下5点です。
・モデルおよびモデル内のデータを表現する
・モデル同士の関連付け(アソシエーション)を表現する
・関連付けられているモデル間の継承階層を表現する
・データをデータベースで永続化する前にバリデーション(検証)を行なう
・データベースをオブジェクト指向スタイルで操作する
ORM (オブジェクト/リレーショナルマッピング) システム
データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法で、アプリケーションが持つリッチなオブジェクトをリレーショナルデータベース(RDBMS)のテーブルに接続することです。ORMを用いると、SQL文を直接書くかわりにわずかなアクセスコードを書くだけで、アプリケーションにおけるオブジェクトの属性やリレーションシップをデータベースに保存することもデータベースから読み出すこともできるようになります。
3.Active Recordのモデルを作成する
Active Recordモデルの作成は非常に簡単です。以下のようにApplicationRecordクラスのサブクラスを作成するだけで完了します。下記では、Productモデルを作成し、データベースのproductsテーブルにマッピングされます。
class Product < ApplicationRecord
end
4.CRUD: データの読み書き
CRUDとは、4つのデータベース操作を表す「Create」「Read」「Update」「Delete」の頭字語です。Active Recordはこれらのメソッドを自動的に作成するので、テーブルに保存されているデータをアプリケーションで操作できるようになります。
Create
Active Recordのオブジェクトはハッシュやブロックから作成できます。また、作成後に属性を手動で追加できます。newメソッドを実行すると単に新しいオブジェクトが返されますが、createを実行すると新しいオブジェクトが返され、さらにデータベースに保存されます。
Userというモデルにnameとdescriptionという属性があるとすると、createメソッドで新しいレコードが1つ作成され、データベースに保存されます。
def create
user = User.create(name: "David", description: "Code")
end
Read
Active Recordは、データベース内のデータにアクセスできる高機能なAPIを提供します。
例えば、ユーザーの一覧を見たい場合は、indexアクションで全てのユーザー情報をGETします。
def index
users = User.all
end
Update
Active Recordオブジェクトを取得すると、オブジェクトの属性を変更してデータベースに保存できるようになります。
user = User.find_by(name: 'David')
user.update(name: 'Dave')
Delete
他のメソッドと同様、Active Recordオブジェクトを取得すると、そのオブジェクトをdestroyしてデータベースから削除できます。
user = User.find_by(name: 'David')
user.destroy
5.バリデーション(検証)
Active Recordを使って、モデルがデータベースに書き込まれる前にモデルの状態をバリデーション(検証: validation)できます。Active Recordにはモデルチェック用のさまざまなメソッドが用意されており、属性が空でないかどうか、属性が一意かどうか、既にデータベースにないかどうか、特定のフォーマットに沿っているかどうか、多岐にわたったバリデーションが行えます。
バリデーションは、データベースを永続化するうえで極めて重要です。そのため、save、updateメソッドは、バリデーションに失敗するとfalseを返します。このとき実際のデータベース操作は行われません。上のメソッドにはそれぞれ破壊的なバージョン (save!、update!) があり、こちらは検証に失敗した場合にさらに厳しい対応、つまりActiveRecord::RecordInvalid例外を発生します。
class User < ApplicationRecord
validates :name, presence: true
end
user = User.new
user.save # => false
user.save! # => ActiveRecord::RecordInvalid: Validation failed: Name can't be blank
if user.save # => true
redirect_to user, notice: "ユーザー「#{user.name}」を登録しました。"
else
render :new
end