【CakePHP入門】テーブルレコードを削除する方法(delete)

こんにちは!フリーエンジニアのせきです。

CakePHPには、テーブルのレコードを削除する機能があります。

この記事では、

・レコードを削除する方法が知りたい
・レコードを複数削除する方法が知りたい

という基本的な内容から、

・関連のある他のテーブルのレコードも削除する方法が知りたい

といった応用的な内容に関しても解説していきます。

今回はそんなテーブルのレコードを削除する方法ついて、わかりやすく解説します!

目次

レコードを1件削除する方法

Entityを指定して削除する方法

レコードを1件削除するには、Tableクラスのdeleteを使用します。

使い方は以下のようになります。

delete(エンティティ)

引数には削除するレコードのエンティティを指定します。

CakePHP2以前では、引数にレコードのプライマリキーとなるIDを指定しました。

CakePHP3から変更されていますので、注意してください。

戻り値として削除した件数を返します

サンプルアプリケーションで確認してみます。

以下のような成績テーブルを使用します。

テーブル定義

create table student_scores
(
    id int not null auto_increment, -- ID
    name varchar(32), -- 名前
    subject_id int, -- 教科ID
    score int, -- 点数
    primary key (ID)
);

以下のデータを登録します。

初期データ

idnamesubject_idscore
1Suzuki180
2Suzuki272
3Nakata190
4Nakata282
5Yamada178
6Yamada256

成績テーブルのEntityModelを作成します。

src\Model\Entity\StudentScore.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class StudentScore extends Entity
{
}

src\Model\Table\StudentScoresTable.php

<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class StudentScoresTable extends Table
{
}

成績テーブルのデータを一覧表示するTemplateを作成します。

src\Template\StudentScores\index.ctp

<table>
    <thead>
        <tr>
            <th>id</th>
            <th>name</th>
            <th>subject_id</th>
            <th>score</th>
        </tr>
    </thead>
    <tbody>
        <?php foreach ($studentScores as $studentScore): ?>
        <tr>
            <td><?= $studentScore->id ?></td>
            <td><?= $studentScore->name ?></td>
            <td><?= $studentScore->subject_id ?></td>
            <td><?= $studentScore->score ?></td>
        </tr>
        <?php endforeach; ?>
    </tbody>
</table>

Contorollerを作成します。

一覧表示のindexメソッドレコード削除のdeleteRecordメソッドを記述します。

src\Controller\StudentScoresController.php

<?php
namespace App\Controller;

use App\Controller\AppController;
use Cake\ORM\TableRegistry;

class StudentScoresController extends AppController
{

    public function index()
    {
        $this->set('studentScores', $this->StudentScores->find('all'));
    }

    public function deleteRecord()
    {
        $entity = $this->StudentScores->get(2);
        $this->StudentScores->delete($entity);

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

deleteRecordメソッドでは、まず「$entity = $this->StudentScores->get(2);」で、成績テーブルからidが2であるレコードのエンティティを取得します。

次に「$this->StudentScores->delete($entity);」で、取得したエンティティをdeleteに渡して、レコードを削除しています。

最後は、一覧画面にリダイレクトしています。

リダイレクトについては、以下の記事で詳しく解説しています。

一覧画面にアクセスしてみます。

http://[サーバ名]/[プロジェクト名]/StudentScores/
001

レコード削除を実行します。

http://[サーバ名]/[プロジェクト名]/StudentScores/deleteRecord
002

idが2であるレコードが削除されています。

複数のレコードを削除する方法

条件を指定して削除する方法

deleteは1件のレコードを削除する時にしか使えません。

複数のレコードを削除するには、deleteAllを使用します。

使い方は以下のようになります。

deleteAll(削除条件の配列)

引数には削除条件を指定します。

[‘カラム名’ => 値]のように指定すると、指定したカラムの値が指定した値と等しいレコードをすべて削除します。

deleteと同様に、戻り値として削除した件数を返します

先ほどの成績テーブルで、subject_idが2のレコードを削除してみます。

StudentScoresControllerのdeleteRecordメソッドを以下のように修正します。

    public function deleteRecord()
    {
        $this->StudentScores->deleteAll(['subject_id' => 2]);

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

削除条件は「[‘subject_id’ => 2]」になります。

データを初期データに戻し、レコード削除を実行します。

003

subject_idが2である3件が削除されました。

削除条件は、配列の要素を増やし複数指定することもできます

以下は、nameが’Yamada’であり、scoreが60より小さいレコードを削除するように指定しています。

    public function deleteRecord()
    {
        $this->StudentScores->deleteAll([
                                'name' => 'Yamada',
                                'score <'  =>  60
                            ]);

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

再び初期データに戻し、レコード削除を実行します。

004

条件に当てはまるidが6のレコードが削除されました。

全件削除する方法

deleteAllは引数を省略することができません。

全件削除する場合には、引数に空の配列を指定します。

StudentScoresControllerのdeleteRecordメソッドを以下のように修正します。

    public function deleteRecord()
    {
        $this->StudentScores->deleteAll([]);

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

実行すると、全件削除されています。

005

関連のあるテーブルのレコードを削除する方法

レコードを削除する時に、他のテーブルの関連するデータも同時に削除することができます。

先ほど使用した成績テーブルのsubject_idを、教科テーブルで定義します。

テーブル定義

create table subjects
(
    id int not null auto_increment, -- 教科ID
    name varchar(32), -- 教科名
    primary key (ID)
);

以下のデータを登録します。

初期データ

idname
1English
2History

教科テーブルのEntityModelを作成します。

src\Model\Entity\Subject.php

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

class Subject extends Entity
{
}

src\Model\Table\SubjectsTable.php

<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class SubjectsTable extends Table
{
    public function initialize(array $config)
    {
        $this->hasMany('StudentScores', [
            'dependent' => true,
        ]);
    }
}

教科テーブルと成績テーブルは、1つの教科IDに対し複数の成績データが存在するので、「1 対 多」という関係になります。

CakePHPのモデルでは、「1 対 多」の関連をhasManyで定義します。

hasManyで「‘dependent’ => true」を指定した場合、教科テーブルのレコードを削除した時に、成績テーブルの関連するデータは同時に削除されます。

StudentScoresControllerのdeleteRecordメソッドで、教科テーブルのレコードを削除してみます。

    public function deleteRecord()
    {
        $this->loadModel('Subjects');
        $entity = $this->Subjects->get(2);
        $this->Subjects->delete($entity);

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

「$this->loadModel(‘Subjects’);」は、Subjectsモデルを追加で読み込むための記述です。

「$entity = $this->Subjects->get(2);」で、教科テーブルからidが2であるレコードのエンティティを取得します。

次に「$this->Subjects->delete($entity);」で、レコードを削除しています。

これを実行すると、教科IDが2である成績テーブルのレコードも同時に削除されます。

006
(成績テーブルのデータは初期データに戻してから実行しています。)

まとめ

今回はテーブルレコードを削除する方法について解説しました。

間違ってレコードを削除しないためにも、deleteとdeleteAllの使い方はしっかりと覚える必要があります。

テーブルレコードを削除する方法を忘れてしまったら、この記事を思い出して下さい!

この記事を書いた人

フリーランスでWebシステム開発やゲーム開発をしています。
読者の方にプログラミングの面白さをお伝えしたいです。

目次