-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[8.x] Init the traits when the model is being unserialized #37492
[8.x] Init the traits when the model is being unserialized #37492
Conversation
Thanks for this. Please add some tests. :) |
@GrahamCampbell Sure! just gimme a few hours, and I will be back with tests 👍🏼 |
If the model has already been booted, isn't the trait boot now going to run twice? Possible even more times if another model is unserialized? Edit: Nevermind - I see this is for initialization and not booting. |
Can you provide an example of the problem you are trying to solve in your code? |
@taylorotwell, I believe I can think of any scenario of any model that uses any traits with initializations; the initializations won't be executed when the model being unserialized. Also, check the /**
* Create a new Eloquent model instance.
*
* @param array $attributes
* @return void
*/
public function __construct(array $attributes = [])
{
$this->bootIfNotBooted();
$this->initializeTraits();
$this->syncOriginal();
$this->fill($attributes);
} It makes sense that the magic method |
@GrahamCampbell I've added the tests. |
I ran into a problem with this. I put typed property into a trait and initialized in the initialization method. (This sounds a logical design pattern for me, but correct me if I'm wrong.) Then I put the model into cache and fetched; serialize and unserialize methods were called, so __wakeup was activated. Needless to say, trait initialization method ran again and properties were set to default, I lost their state. Example: trait TestTrait
{
protected string|null $property;
protected function initializeTestTrait(): void
{
$this->property = null;
}
}
class TestModel {
use TestTrait;
} I'm not sure whether this should be the expected behaviour. I would say no and here're my reasons.
I have some ideas to solve this, but first please share your option on this. Thank you. |
I believe you can check the property state first before resetting it, like this way: trait TestTrait
{
protected string|null $property;
protected function initializeTestTrait(): void
{
if (! isset($this->property)) {
$this->property = null;
}
}
} |
This change calls the trait initializers when the model is being unserialized; the same happened with the model boot methods.