In Laravel, there isn't a built-in lifecycle hook that triggers after a model and all of its relationships have been saved. However, you can achieve this by manually triggering an event after you've saved the model and its relationships.
Here's a step-by-step solution:
- Create a custom event that you'll dispatch after the model and its relationships have been saved.
- Create a listener for that event which will handle the creation of the other model based on the relationships.
Here's an example of how you might implement this:
First, create the custom event:
// app/Events/AdCreatedWithIndexes.php
namespace App\Events;
use Illuminate\Queue\SerializesModels;
use App\Models\Ad;
class AdCreatedWithIndexes
{
use SerializesModels;
public $ad;
public function __construct(Ad $ad)
{
$this->ad = $ad;
}
}
Next, create the listener:
// app/Listeners/CreateChargeForAd.php
namespace App\Listeners;
use App\Events\AdCreatedWithIndexes;
use App\Models\Charge;
class CreateChargeForAd
{
public function handle(AdCreatedWithIndexes $event)
{
$ad = $event->ad;
// Assuming you have a method to calculate the price based on indexes
$price = $ad->calculatePriceBasedOnIndexes();
// Create the charge model
$charge = new Charge([
'ad_id' => $ad->id,
'price' => $price,
]);
$charge->save();
}
}
Now, you need to register the event and listener in your EventServiceProvider:
// app/Providers/EventServiceProvider.php
protected $listen = [
'App\Events\AdCreatedWithIndexes' => [
'App\Listeners\CreateChargeForAd',
],
];
Finally, after you've saved your Ad model and its relationships, you can dispatch the event:
$ad = new Ad($adData);
$ad->save();
// Save the relationships
foreach ($indexes as $indexData) {
$ad->indexes()->create($indexData);
}
// Dispatch the event after all relationships are saved
event(new AdCreatedWithIndexes($ad));
This way, the CreateChargeForAd listener will only be called after the Ad model and its relationships (indexes) have been saved, ensuring that you have all the necessary data to calculate the price and create the Charge model.