#08 データベース操作の基本 Update:データの更新

前回、「Heroes」モデルの「データの取得」を行った。今回はデータの更新を行う。

  • Create:新規作成
  • Read:データの取得
  • Update:データの更新
  • Delete:データの削除

データの更新はデータの新規作成と似ているが、既にあるエンティティーを修正して保存するという点が異なる。

流れとして以下のようになる。

  1. 「編集するデータはどのデータか」という情報をサーバー側に伝える
  2. サーバー側はその情報をもとにエンティティーを検索、編集用フォームに設定して表示する
  3. ユーザーがそのフォームを編集し送信する
  4. サーバー側で受け取ったフォームをもとに、サーバー内のエンティティーを更新する

「Heroes」コントローラーに「edit」アクションを追記

「HeroesController」に、「edit」アクションを追加する。

■場所
\htdocs\chococake\src\Controller
■ファイル名
HeroesController.php

<?php
namespace App\Controller;

use App\Controller\AppController;

/**
* 
*/
class HeroesController extends AppController
{
  public function add()
  {
    if ($this->request->is('post')) {
      $hero = $this->Heroes->newEntity();
      $hero = $this->Heroes->patchEntity($hero, $this->request->data);

      if ($this->Heroes->save($hero)) {
        return $this->redirect(['action' => 'index']);
      }
    }
  }

  // indexアクション
  public function index()
  {
    $this->set('heroes', $this->Heroes->find('all'));
  }

  // 今回追記部分。editアクション
  public function edit($id = null)
  {
    $hero = $this->Heroes->get($id);
    if ($this->request->is(['post', 'put'])) {
      $hero = $this->Heroes->patchEntity($hero, $this->request->data);
      if ($this->Heroes->save($hero)) {
        return $this->redirect(['action' => 'index']);
      }
    } else {
      $this->set('hero', $hero);
    }
  }

}

解説

public function edit($id = null)

本講座の「#02 Controller の作成・パラメータを表示・アクションの呼び出し」で説明したが、edit アクションの引数に id を指定する。パ指定することで id のレコードの情報を呼び出し、フォームに表示させることができる。

例として id が「1」のレコードをフォームに表示させるためには、「/chococake/heroes/edit/1」にアクセスすればよい。

$hero = $this->Heroes->get($id);

引数で渡された $id の番号のエンティティーを、モデルの「get」メソッドを使用して取得する。

取得したデータは変数 $hero に格納される。

if ($this->request->is(['post', 'put'])) {

「is」でアクセス方式のチェックを行い、分岐する。

「is」の引数に「post」「put」という配列が用意されている。

「post」はリソースの作成、「put」はリソースの作成、リソースの置換を意味する。

フォームヘルパーを使用してエンティティーの値を更新する場合、「post」と「put」というアクセスもチェックして処理を行わせるようにする必要がある。

チェックが true であれば、以下の if 文内の処理を行う。

$hero = $this->Heroes->patchEntity($hero, $this->request->data);

フォームから送信された値を、エンティティーにマージしている。

get で取得したエンティティー $hero と、フォーム送信された $this->request->data の内容をマージ(結合)させることで、値が変更されたエンティティーが作成され、$hero に格納される。

      if ($this->Heroes->save($hero)) {

「save」メソッドでエンティティーを保存する。

return $this->redirect(['action' => 'index']);

保存が完了したら、「index」アクションにリダイレクトする。

} else {
  $this->set('hero', $hero);
}

「if ($this->request->is(‘post’))」が「false」だった場合、つまり get アクセスされた場合の処理。
$hero の値を「hero」という名前で設定し、フォームに表示している。

次に、この Controller を表示させる View を作成する。

ビューテンプレートのファイル作成

ビューテンプレートファイルに編集画面を表示させる記述をする。

■場所
\htdocs\chococake\src\Template\Heroes
■ファイル名
edit.ctp

<h1>編集</h1>

<!-- フォーム開始タグ -->
<?= $this->Form->create($hero) ?>

<!-- フォームの入力内容をグループ化するタグ -->
<fieldset>
  <!-- 各入力フィールドのinputタグ -->
  <?= $this->Form->input('name') ?>
  <?= $this->Form->input('power') ?>
  <?= $this->Form->input('country') ?>
</fieldset>

<!-- 送信ボタンのタグ -->
<?= $this->Form->button('登録') ?>

<!-- フォーム終了タグ -->
<?= $this->Form->end() ?>

解説

基本的に前回作成した「add.ctp」と同じ。異なる部分のみ解説。

<?= $this->Form->create($hero) ?>

create メソッドの引数に $hero を指定。Controller 側の処理で、編集するエンティティーを $hero 内に格納されている。

create メソッドは、引数にエンティティーのオブジェクトが渡されると、エンティティーを元にフォームが生成される。

エンティティーの中身は、ビューテンプレートの edit.ctp に以下の記述をすると確認できる。

debug($hero);

エンティティーの中身が画面に表示される。

object(App\Model\Entity\Hero) {

  'id' => (int) 1,
  'name' => 'キン肉マン',
  'power' => (int) 95,
  'country' => 'キン肉星',
  '[new]' => false,
  '[accessible]' => [
    '*' => true,
    'id' => false
  ],
  '[dirty]' => [],
  '[original]' => [],
  '[virtual]' => [],
  '[errors]' => [],
  '[invalid]' => [],
  '[repository]' => 'Heroes'

}

以下URLにアクセスすると編集フォームが表示される。
http://localhost/chococake/heroes/edit/1

「編集」ボタンを押下し、「/chococake/heroes/」にリダイレクトされればOK。

CakePHP の一覧