概要
Laravelにおけるデータモデルの操作をまとめる。
例としてStickyNoteというアプリケーションを仮定する。StickyNoteは付箋紙のようなアプリケーションで、タイトルとメモ本文を扱う。このアプリケーションを通して、フォーム入力、データの読み込み、書き込み、更新、削除の流れをそれぞれ整理。
データ構造
マイグレーションファイル
マイグレーションファイルにより、StickyNotesの個々の付箋メモのデータ構造を定義。タイトル(title
)とメモ本文(body
)を定義している。
|
class CreateDiariesTable extends Migration { ..... public function up() { Schema::create('diaries', function (Blueprint $table) { $table->bigIncrements('id'); $table->string('title', 20); $table->string('title', 100); $table->datetime('created_at'); $table->datetime('updated_at'); }); } ..... } |
データベース
マイグレーションの結果得られるテーブルの構造。
|
mysql> describe diaries; +------------+-----------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-----------------+------+-----+---------+----------------+ | id | bigint unsigned | NO | PRI | NULL | auto_increment | | title | varchar(20) | NO | | NULL | | | body | varchar(100) | NO | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+-----------------+------+-----+---------+----------------+ 5 rows in set (0.00 sec) |
データの読み込み
ルーティング
ドメイン名/sticky_note
のURL指定に対してコントローラーStickyNoteController
のindex
アクションを呼び出す。
routes/web.php
|
Route::get('/sticky_note', 'StickyNoteController@index'); |
コントローラーでの処理~all()による全データ取得
全データ取得はコントローラーのスタティックメソッドall()
を使い、結果はレコード単位の配列で得られる。
ここでは、
index
アクションで$sticky_notes
に表示対象の全データを取得
- 取得した配列をビューに渡して遷移
- モデルを記述するときはフルパスで書くか冒頭で
use
宣言
app/Https/Controllers/StickyNoteController.php
\App\StickyNote
のようにモデルをフルパスで指定する必要がある。あるいは冒頭でuse \App\StickyNote
としてもよい。
|
class StickyNoteController extends Controller { ..... public function index() { // データベースから全データ取得 $sticky_notes = \App\StickyNote::all(); // ページ遷移 return view('sticky_note.index', [ 'title' => '付箋紙', 'sticky_notes' => $sticky_notes, ]); } ..... } |
ビューによる表示
ビューで受け取った配列をループで表示させている。データベースのカラムに対応した属性で、各カラムのデータが得られる。
resources/views/sticky_note/index.blade.html
|
@forelse ($sticky_notes as $sticky_note) <div>{{ $sticky_note->title }}</div> <div>{{ $sticky_note->body }}</div> @empty <p>付箋紙が登録されていません。</p> @endforelse |
データの書き込み
フォームでの入力と送信
書き込むデータをフォーム入力し、POTSTで送信する。
resources/views/create.blade.php
|
<form method="post" action="/sticky_note"> @csrf <div> <label>タイトル: <input type="text" name="title"></label> </div> <div> <label>メモ内容: <input type="text" name="body"></label> </div> <input type="submit" value="送信"> </form> |
ルーティング~POSTに対する書き込み処理
POSTのルーティング先をコントローラーのstore()
アクションとしている。
routes/web.php
|
Route::post('/sticky_note', 'StickyNoteController@store'); |
コントローラーでの処理~create()によるデータ書き込み
ルーティング先のアクションではフォームリクエストを引数にとり、マスアサインメントと登録処理を1行で記述している。
また、アクションで引用するモデルとフォームリクエストのクラスをuse
でインポートしている。
ここでは、
- コントローラーの冒頭で、モデル
StickyNote
とフォームリクエストStickyNoteRequest
をuse
でインポート
- フォームリクエスト
StickyNoteRequest
を引数にとっている
- リクエストの
only()
メソッドでマスアサイン
- アサイン結果をモデル
StickyNote
のcreate()
スタティックメソッドの引数に与え、データを登録
- トップページにリダイレクト
app/Https/Controllers/StickyNoteController.php
|
// カスタムモデル use App\StickyNote; // カスタムフォームリクエスト use App\Http\Requests\StickyNoteRequest; class StickyNoteController extends Controller { ..... public function store(StickyNoteRequest $request) { // マスアサインメント結果をDBに新規登録 StickyNote::create($request->only(['title', 'body'])); // トップページにリダイレクト return redirect('/sticky_note'); } ..... } |
モデルでの$fillable定義
コントローラーでのマスアサインメントを有効にするため、データモデルで$fillable
プロパティーを定義。
ここでは、StickyNote
モデルクラスで$fillable
をpublic
宣言して、読み込むプロパティーをtitle
とbody
の2つに限定している。
app/StickyNote.php
|
class StickyNote extends Model { public $fillable = ['title', 'body']; } |
データの更新
ルーティング
- 更新対象を指定するデータの
id
がルートパラメーターで指定されてGETされることを想定
- URLにルートパラメーター
{id}
を含めている
- GETメソッドでトップページなど他のページを区別するために、URLに
/edit
を付けている
- GETを受け取ったら
edit
アクションにルーティング
- たとえばアンカータグでここに飛ばしたい場合は、
url()
ヘルパーを使って以下のように指定する
<a href="{{ url('/diaries') . '/' . $diary->id . '/edit' }}">
routes/web.php
|
Route::get('/sticky_note/{id}/edit', 'StickyNoteController@edit') ->where('id', '^\d+$'); |
コントローラーでの処理~find()による更新対象の取得
- ルーティングで設定されたルートパラメーターは、アクションの引数で参照する
- モデルの
find()
スタティックメソッドで、id
に対応するモデルのインスタンスを取得
- 取得したモデルインスタンスを、更新用のフォームを持つビューに渡す
- 遷移先のビューで
id
に対応するデータを初期表示するため
app/Https/Controllers/StickyNoteController.php
|
public function edit($id) { // ルートパラメーターから更新するインスタンスを取得 $sticky_note = \App\StickyNote::find($id); // 更新するインスタンスを渡して編集ページを表示 return view('edit', [ 'title' => '内容編集', 'body' => $body, ]); } |
フォームでの入力と送信
- 更新用のフォームを表示する
- フォームの各要素に、受け取ったデータのタイトルと本文を初期表示する
- 更新結果はPATCHメソッドで送信
- HTTPにはGETとPOSTしかないので、
form
タグではPOSTを指定し、@method()
ディレクティブでPATCHを指定している
- 送信先の
action
で、id
をルートパラメーターとして付加している
resources/views/edit.blade.php
|
<form method="post" action="{{ url('/sticky_note') . '/' . $sticky_note->id }}"> @csrf @method('PATCH') <div> <label>タイトル: <input type="text" name="title" value="{{ $sticky_note->title }}"> </label> </div> <div> <label>メモ内容: <input type="text" name="body" value="{{ $sticky_note->body }}"> </label> </div> <input type="submit" value="保存"> </form> |
ルーティング
PATCHメソッドによるルートパラメーターid
を含むURLへの送信を、update()
アクションにルーティング。
routes/web.php
|
Route::patch('/sticky_note/{id}', 'StickyNoteController@update') ->where('id', '^\d+$'); |
コントローラーでの処理~update()による更新処理
データの書き込みと同じような手順。
- ルートパラメーターを引数で受け取り
- 引数の順番は、フォームリクエスト、ルートパラメーターの順番
find()
の引数にid
を与えてデータを取得
- マスアサインメントでデータを更新
- トップページへリダイレクト
app/Https/Controllers/StickyNoteController.php
|
public function update(StickyNoteRequest $request, $id) { // ルートパラメーターから更新するインスタンスを取得 $diary = \App\StickyNote::find($id); // マスアサインメント結果をで更新 $diary->update($request->only(['title', 'body'])); // トップページへリダイレクト return redirect('/sticky_note'); } |
データの削除
ビュー~削除対象指定
- 全データを表示する際に、各データをフォームで表示し、データごとに削除ボタンを置く
- 削除ボタンが押されると、DELETEメソッドで
id
をルートパラメーターに含むURLを呼び出す
- HTTPにはGETとPOSTしかないため、@methodディレクティブでDELETEを指定
routes/web.php
|
@forelse ($sticky_notes as $sticky_note) <form method="post" action="{{ url('/sticky_note') . '/' . $sticky_note->id }}"> @csrf @method('DELETE') <div>{{ $sticky_note->title }}</div> <input type="submit" value="削除"> </form> @empty <p>付箋紙が登録されていません。</p> @endforelse |
ルーティング
DELETEメソッドで所定のURLが要求された場合に、destroy()
アクションにルーティング。
routes/web.php
|
Route::delete('/diaries/{id}', 'DiaryController@destroy') ->where('id', '^\d+$'); |
コントローラーでの処理~delete()による削除
- ルートパラメーターで受け取ったidでデータを取り出し
- 得られたデータを
delete()
で削除
- トップページにリダイレクト
app/Https/Controllers/StickyNoteController.php
|
public function destroy($id) { // ルートパラメーターから削除する対象を取得 $Sticky_note = \App\StickyNote::find($id); // 対象を削除 $Stocky_note->delete(); // トップページへリダイレクト return redirect('/sticky_note'); } |