頭の整理のためのメモなので、考え方だけです。
実際のコードに関しては、記載しません。
要求
- 途中で何らかエラーがあったらすべてをロールバック
- エラー内容はすべて表示
どういう流れにするか
最初にバリデーションをしてから、最後にsaveをする。
プログラムイメージ
<?php
// この前にはファイルオープンやらなにやら前処理があるはず
foreach ($datas as $i => $data)
{
try
{
$model = Model_Hoge()::forge($data);
$model->validate();
$models[] = $model;
}
catch (Exception_ValidateError $e)
{
$errors[] = $e->show_errors();
}
}
// エラー時に格納したものがなければ保存
if (count($errors) === 0)
{
foreach ($models as $model)
{
$model->save();
}
}
おそらくこれで要求は満たせる
1:Nの関連性があるモデルはどうするか
1:Nの関連性があるモデルがある場合は、どうしたらいいのか。
プログラムイメージ
<?php
// この前にはファイルオープンやらなにやら前処理があるはず
// Model_Hoge (1) -> Model_Fuga (N) という継承とする
foreach ($datas as $data)
{
try
{
// hogeのバリデーション
$hoge = Model_Hoge::forge($data);
$hoge->validate();
// fugaのバリデーション
$fuga = Model_Fuga::forge($data);
$fuga->validate();
// 問題なければ親のモデルにセット
$hoge->fuga[] = $fuga;
// 最後にsaveするので、一旦格納
$models[] = $hoge;
}
catch (Exception_ValidateError $e)
{
$errors[] = $e->show_errors();
}
}
if (count($errors) === 0)
{
foreach ($models as $model)
{
// まとめてsaveする
$model->save();
}
}
こんな感じでできるんじゃないかなー。
8/28追記
以下でも良い。というか以下の方がやりやすかった。
別案
<?php
// この前にはファイルオープンやらなにやら前処理があるはず
// Model_Hoge (1) -> Model_Fuga (N) という継承とする
DB::start_transaction();
foreach ($datas as $data)
{
try
{
// hogeのバリデーション
$hoge = Model_Hoge::forge($data);
$hoge->validate();
// fugaのバリデーション
$fuga = Model_Fuga::forge($data);
$fuga->validate();
// 問題なければ親のモデルにセット
$hoge->fuga[] = $fuga;
$hoge->save();
// ここでsaveしているので
// 同じ内容を入れたくない場合は、2週目以降検索すればよい
}
catch (Exception_ValidateError $e)
{
$errors[] = $e->show_errors();
}
}
if (count($errors) === 0)
{
DB::commit_transaction();
}
else
{
DB::rollback_transaction();
}