この投稿では、Laravelを用いてCSVファイルからCustomerテーブルとReservationテーブルに同時にデータを登録し、関連するRoomテーブルのステータス更新も行う一括インポート処理の実装方法を紹介します。
概要
- CSVには顧客情報と予約情報を含める
- 1レコードごとにCustomerを追加し、対応するReservationを作成
- 予約で使用されるRoomのstatusを
2
に更新 - トランザクション処理により整合性を確保
1. ルーティングの定義
// routes/web.php
Route::post('/admin/import-csv', [CsvImportController::class, 'importCsv'])->name('admin.import.csv');
2. フォームの作成(CSVアップロード画面)
<!-- resources/views/admin/import_csv.blade.php -->
<form method="POST" action="{{ route('admin.import.csv') }}" enctype="multipart/form-data">
@csrf
<input type="file" name="csv_file" required>
<button type="submit" class="btn btn-primary mt-2">インポート</button>
</form>
3. コントローラーの実装
// app/Http/Controllers/Admin/CsvImportController.php
use App\Models\Customer;
use App\Models\Reservation;
use App\Models\Room;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class CsvImportController extends Controller
{
public function importCsv(Request $request)
{
$request->validate([
'csv_file' => 'required|file|mimes:csv,txt',
]);
$file = $request->file('csv_file');
$handle = fopen($file->getRealPath(), 'r');
$header = fgetcsv($handle);
DB::beginTransaction();
try {
while (($row = fgetcsv($handle)) !== false) {
$data = array_combine($header, $row);
$customer = Customer::create([
'surname_kana' => $data['surname_kana'],
'name_kana' => $data['name_kana'],
'tel' => $data['tel'],
'zipcode' => $data['zipcode'],
'address' => $data['address'],
]);
$roomId = explode(' ', $data['room_id'])[0];
Reservation::create([
'customer_id' => $customer->id,
'room_id' => $roomId,
'status' => $data['status'],
'plan' => $data['plan'],
'plan_tanka' => $data['plan_tanka'] ?? 0,
]);
Room::where('id', $roomId)->update(['status' => 2]);
}
DB::commit();
return back()->with('success', 'CSVインポートが完了しました');
} catch (\Exception $e) {
DB::rollBack();
Log::error('CSVインポート失敗: '.$e->getMessage());
return back()->with('error', 'インポート中にエラーが発生しました');
}
}
}
4. CSVファイルのサンプル形式
surname_kana,name_kana,tel,zipcode,address,room_id,status,plan,plan_tanka
マエガワ,ヒデタカ,09012345678,5300001,大阪市北区,105 葵,仮予約,ビジネス,8000
まとめ
- CSVの内容をもとにCustomerとReservationを関連付けて登録
- 対応するRoomのstatusを一括で更新
- Laravelのトランザクション処理を活用することで、処理中の不整合も防止
今後はバリデーション強化や、既存データの上書き確認なども検討できます。
コメント