こんにちは!フリーエンジニアのせきです。
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に渡して、レコードを削除しています。
最後は、一覧画面にリダイレクトしています。
リダイレクトについては、以下の記事で詳しく解説しています。
一覧画面にアクセスしてみます。
http://[サーバ名]/[プロジェクト名]/StudentScores/
レコード削除を実行します。
http://[サーバ名]/[プロジェクト名]/StudentScores/deleteRecord
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]」になります。
データを初期データに戻し、レコード削除を実行します。
subject_idが2である3件が削除されました。
削除条件は、配列の要素を増やし複数指定することもできます。
以下は、nameが’Yamada’であり、scoreが60より小さいレコードを削除するように指定しています。
public function deleteRecord() { $this->StudentScores->deleteAll([ 'name' => 'Yamada', 'score <' => 60 ]); return $this->redirect(['action' => 'index']); }
再び初期データに戻し、レコード削除を実行します。
条件に当てはまるidが6のレコードが削除されました。
全件削除する方法
deleteAllは引数を省略することができません。
全件削除する場合には、引数に空の配列を指定します。
StudentScoresControllerのdeleteRecordメソッドを以下のように修正します。
public function deleteRecord() { $this->StudentScores->deleteAll([]); return $this->redirect(['action' => 'index']); }
実行すると、全件削除されています。
関連のあるテーブルのレコードを削除する方法
レコードを削除する時に、他のテーブルの関連するデータも同時に削除することができます。
先ほど使用した成績テーブルのsubject_idを、教科テーブルで定義します。
テーブル定義
create table subjects ( id int not null auto_increment, -- 教科ID name varchar(32), -- 教科名 primary key (ID) );
以下のデータを登録します。
初期データ
id | name |
---|---|
1 | English |
2 | History |
教科テーブルの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である成績テーブルのレコードも同時に削除されます。
(成績テーブルのデータは初期データに戻してから実行しています。)
まとめ
今回はテーブルレコードを削除する方法について解説しました。
間違ってレコードを削除しないためにも、deleteとdeleteAllの使い方はしっかりと覚える必要があります。
テーブルレコードを削除する方法を忘れてしまったら、この記事を思い出して下さい!