0
0

【Laravel】CSVファイルの中身にバリデーション(maatwebsite/excel)

Posted at

以前に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でエラーハンドリングを追加しました。
これでエラーメッセージも表示されるようになりました。

以上、誰かの参考になれば幸いです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0