Skip to content

Commit 256abae

Browse files
committed
Fire a new becoming event for the become feature to allow hooking into the transformation process
1 parent a22a2e4 commit 256abae

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

readme.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,14 @@ The `become()` method will return a new instance of the specified child model wi
239239

240240
This is also useful when you're using observers or callbacks, since the specific child model's behavior will be triggered after the transition.
241241

242+
A new model event is fired when a model is _becoming_ another type, you may listen to it like so:
243+
244+
```php
245+
ShippedOrder::becoming(function ($shippedOrder) {
246+
// Do something before the model is saved...
247+
});
248+
```
249+
242250
## Laravel Nova Support
243251

244252
If you want to use share parent Nova resources with child models, you may register the following provider at the end of the boot method of your NovaServiceProvider:

src/HasChildren.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ trait HasChildren
2020
*/
2121
protected $hasChildren = true;
2222

23+
/**
24+
* Register a becoming model event with the dispatcher.
25+
*
26+
* @param \Illuminate\Events\QueuedClosure|callable|array|class-string $callback
27+
*/
28+
public static function becoming($callback): void
29+
{
30+
static::registerModelEvent('becoming', $callback);
31+
}
32+
2333
/**
2434
* Register a model event with the dispatcher.
2535
*
@@ -268,6 +278,8 @@ public function become($class)
268278
$instance->setConnection($this->getConnectionName());
269279

270280
$instance->setRelations($this->relations);
281+
282+
$instance->fireModelEvent('becoming', false);
271283
});
272284
}
273285

tests/Features/ModelsCanBecomeOtherTypesTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Parental\Tests\Features;
44

5+
use Illuminate\Support\Facades\Event;
56
use Parental\Tests\Models\Car;
67
use Parental\Tests\Models\ClawHammer;
78
use Parental\Tests\Models\Mallet;
@@ -103,4 +104,31 @@ public function come_calls_model_events_on_specified_model(): void
103104

104105
$this->assertTrue($carEventCalled);
105106
}
107+
108+
/** @test */
109+
public function fires_becoming_model_event(): void
110+
{
111+
$becomingEventCalledCount = 0;
112+
113+
Event::listen('eloquent.becoming: ' . Car::class, function () use (&$becomingEventCalledCount) {
114+
$becomingEventCalledCount++;
115+
});
116+
117+
Car::becoming(function () use (&$becomingEventCalledCount) {
118+
$becomingEventCalledCount++;
119+
});
120+
121+
$vehicle = Vehicle::create(['type' => 'truck']);
122+
123+
$this->assertEquals(0, $becomingEventCalledCount);
124+
125+
$car = $vehicle->become(Car::class);
126+
$car->save();
127+
128+
$this->assertInstanceOf(Car::class, $car);
129+
$this->assertEquals('car', $car->type);
130+
$this->assertEquals($vehicle->id, $car->id);
131+
132+
$this->assertEquals(2, $becomingEventCalledCount);
133+
}
106134
}

0 commit comments

Comments
 (0)