はじめに
データ新規作成時、あらかじめ ID を採番しておいて、オブジェクトを持ちまわしていました
しかし、そのオブジェクトの保存処理後、採番していた ID とは違う ID で保存されていたのです
結論
patchEntity() の返り値のエンティティの id に値を設定すれば OK
CakePHPUserRepository.php
// ユーザーを保存する
public function save(User $user): UserId
{
$model = TableRegistry::getTableLocator()->get('Users');
$saveData = [
'Users' => [
// ここで ID を設定しても保存処理に採用されない
// 'id' => $user->getId()->getValue(),
'username' => $user->getUsername()->getValue(),
'password' => $user->getPassword()->getValue(),
'role' => $user->getRole()->getValue(),
],
];
$entity = $model->newEmptyEntity();
$entity = $model->patchEntity($entity, $saveData);
// patchEntity() 時に ID が消え去るため、明示的に設定
$entity->id = $user->getId()->getValue();
$saved = $model->saveOrFail($entity);
return new UserId($saved->id);
}
バージョン
- PHP
- 8.0.10
- CakePHP
- 4.3.0
状況
プロダクトコード
ユーザー新規追加APIで、以下のような雰囲気のコードを書いていました
CakePHPUserRepository.php
// 独自クラス
// ユーザーID を UUID で採番する
public function assignId(): UserId
{
return new UserId(\Cake\Utility\Text::uuid());
}
// ユーザーを保存する
public function save(User $user): UserId
{
// (略)↑の結論と同様
}
UsersController.php
// ユーザー新規追加アクション
public function add(): void
{
$jsonData = $this->request->getData();
$userRepository = new CakePHPUserRepository();
$userId = $userRepository->save(
new User(
$userRepository->assignId(),
new Username($jsonData['username']),
new Password($jsonData['password']),
new Role($jsonData['role']),
)
);
$data = ['userId' => $userId->getValue()];
$this->set($data);
$this->viewBuilder()->setClassName('Json')->setOption('serialize', ['userId']);
}
以下の独自クラスにゲッターメソッド(getXxx()
、getValue()
)定義
- User.php
- UserId.php
- Username.php
- Password.php
- Role.php
テストコード
しかし、テストを実行すると、ID が一致しないのです
CakePHPUserRepositoryTest.php
public function test_ユーザー情報を保存すること(): void
{
$expect = new UserId('01509588-3882-42dd-9ab2-485e8e579a8e');
$user = new User(
$expect,
new LoginId('test'),
new Password('p@ssw0rd1'),
new RoleName('admin'),
);
$actual = (new CakePHPUserRepository())->save($user);
$this->assertEquals($expect, $actual);
}
ということで、上記の結論となります
おわりに
テストコードを作成して実行するまで、全然気づきませんでした
この記事が他のエンジニアの助けになれば幸いです