こんにちは!フリーエンジニアのせきです。
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)
);
以下のデータを登録します。
初期データ
id | name | subject_id | score |
1 | Suzuki | 1 | 80 |
2 | Suzuki | 2 | 72 |
3 | Nakata | 1 | 90 |
4 | Nakata | 2 | 82 |
5 | Yamada | 1 | 78 |
6 | Yamada | 2 | 56 |
成績テーブルのEntityとModelを作成します。
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に渡して、レコードを削除しています。
最後は、一覧画面にリダイレクトしています。
リダイレクトについては、以下の記事で詳しく解説しています。
【CakePHP】リダイレクトで別ページに遷移する方法(redirect/header)
更新日 : 2019年4月22日
一覧画面にアクセスしてみます。
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)
);
以下のデータを登録します。
初期データ
教科テーブルのEntityとModelを作成します。
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の使い方はしっかりと覚える必要があります。
テーブルレコードを削除する方法を忘れてしまったら、この記事を思い出して下さい!