以前にCSVファイルをインポートする記事を書きましたが、今回はCSVファイルの中身にバリデーションチェックをかける方法について書きたいと思います。
前回のCSVファイルインポートの記事はこちらです。
やりたいこと
前回と同様に、下記のようなCSVデータをアップロードします。
企業名,郵便番号,住所,電話番号,代表者名,担当者名,備考
テスト02株式会社,2203456,埼玉県上尾市井戸木,090-4736-0924,佐藤,中島,テストです
- 備考以外はすべて必須項目
- 企業名は一意な値としたい
Importクラスの作成
- インターフェイスにwithValidationを追加(useで読み込みを忘れずに)
- rulesメソッドでバリデーションのルールを設定
- customValidationMessagesメソッドでメッセージをカスタマイズする
以上を反映させたコードが下記です。
app/Imports/CompaniesImport.php
use App\Models\Company;
use Illuminate\Validation\Rule;
use Maatwebsite\Excel\Concerns\Importable;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithValidation;
class CompaniesImport implements ToModel, WithHeadingRow, WithValidation
{
use Importable;
public function model(array $row)
{
return new Company([
'name' => $row['企業名'],
'post_code' => $row['郵便番号'],
'address' => $row['住所'],
'tel' => $row['電話番号'],
'ceo_name' => $row['代表者名'],
'responsible_person_name' => $row['担当者名'],
'note' => $row['備考'],
]);
}
public function rules(): array
{
return [
'企業名' => ['required', Rule::unique('companies', 'name')],
'郵便番号' => ['required'],
'住所' => ['required'],
'電話番号' => ['required'],
'代表者名' => ['required'],
'担当者名' => ['required'],
];
}
public function customValidationMessages(): array
{
return [
'企業名.required' => '企業名は必須項目です。',
'企業名.unique' => 'すでに登録されている企業名があります。',
'郵便番号.required' => '郵便番号は必須項目です。',
'住所.required' => '住所は必須項目です。',
'電話番号.required' => '電話番号は必須項目です。',
'代表者名.required' => '代表者名は必須項目です。',
'担当者名.required' => '担当者名は必須項目です。',
];
}
}
注意点
rulesメソッドやcustomValidationMessagesメソッドのフィールド名は、CSVのヘッダー行と一致している必要があります。
例えば「企業名」の場合、
'name' => ['required', Rule::unique('companies', 'name')],
と書くと、うまくいきません。
modelメソッドで$row['企業名]
とヘッダー設定しているので、それに対応するルール定義も同じ日本語のフィールド名である必要があります。
Controllerの作成
app/Http/Controllers/CompanyController.php
public function import(ImportCsvRequest $request)
{
$file = $request->file('file');
try {
Excel::import(new CompaniesImport, $file);
return redirect()
->route('company.index')
->with('message', 'データが正常にインポートされました');
} catch (\Exception $ex) {
return redirect()
->route('company.create')
->with('error', 'データのインポート中にエラーが発生しました: ' . $ex->getMessage());
}
}
前回と違うところは、try,catchでエラーハンドリングを追加しました。
これでエラーメッセージも表示されるようになりました。
以上、誰かの参考になれば幸いです。