This is more like model event listener creating some number of other records connected to that particular record creating and using a foreign key. However I want this to occur during seeding. Let’s say I have a Flight model/table, I want each time a create a record either through manually or seeding, it automatically creates the seats (On the Seat model or table) which users can book. Also the number of seats created for that flight depends on a column on the flight called “available_seats”. I have already implemented this using model event listeners but it doesn’t seem to work when I seed my flights. Now because seats are usually large in number, I may need ways to optimize the seats creation time both manually and seeding
This is my Flight Seeder file:
<?php
namespace DatabaseSeeders;
use AppModelsSeat;
use AppModelsFlight;
use IlluminateDatabaseSeeder;
use IlluminateDatabaseConsoleSeedsWithoutModelEvents;
class FlightSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Creating large record of flights using factories
$flights = Flight::factory(20)->create();
foreach ($flights as $flight) {
$this->createSeats($flight);
}
}
// Function to create flight seats
public function createSeats(Flight $flight)
{
// Define the seat classes and the number of seats in each class
$seatClasses = [
'economy' => floor(0.70 * $flight->available_seat),
'premium economy' => floor(0.10 * $flight->available_seat),
'business' => floor(0.15 * $flight->available_seat),
'first class' => floor(0.05 * $flight->available_seat),
];
foreach ($seatClasses as $class => $count) {
// Determining seat price based on price
if ($class == 'economy') {
$price = $flight->economy_price;
} else if ($class == 'premium economy') {
$price = $flight->premium_economy_price;
} else if ($class == 'business') {
$price = $flight->business_price;
} else {
$price = $flight->first_class_price;
}
// Loop to create class seats
for ($i = 1; $i <= $count; $i++) {
Seat::create([
'flight_id' => $flight->id,
'seat_number' => strtoupper(substr($class, 0, 1)) . $i, // Example: E1, E2, ..., B1, B2, ...
'seat_class' => $class,
'price' => $price,
'status' => 'available'
]);
}
}
}
}
It only seeds the flight table but doesn’t create the seats as expected. I’m I missing something or are there ways to connect it to my model event listener? Here is my flight factory code if required:
<?php
namespace DatabaseFactories;
use AppCustomFunctions;
use CarbonCarbon;
use IlluminateDatabaseEloquentFactoriesFactory;
/**
* @extends IlluminateDatabaseEloquentFactoriesFactory<AppModelsFlight>
*/
class FlightFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
// Date extension by days
$dateAddition = rand(0, 7);
// Base flight price
$base_price = fake()->randomFloat(2, 1000, 5000);
return [
'flight_id' => Functions::generateFlightID(),
'airline_id' => rand(1, 5), // Random airline ID between 1 and 10
'origin_id' => rand(1, 10), // Random origin ID between 1 and 10
'destination_id' => rand(1, 10), // Random destination ID between 1 and 10
'departure_time' => Carbon::now()->addDays($dateAddition)->format('Y-m-d H:i:s'), // Departure at least today or in the next 7 days
'arrival_time' => fake()->dateTimeBetween(Carbon::now()->addDays($dateAddition), Carbon::now()->addDays($dateAddition + 3)), // Arrival sometime between departure date and 3 days after
'economy_price' => $base_price, // Price between 100.00 and 1000.00
'premium_economy_price' => $base_price + 500, // Price dependent on the economy/base price
'business_price' => $base_price + 1000, // Price dependent on the economy/base price
'first_class_price' => $base_price + 3000, // Price dependent on the economy/base price
'available_seats' => rand(150, 300)
];
}
}