Skip to content
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

[5.4] add ability to define reloaded relationships #20602

Closed
wants to merge 1 commit into from
Closed

[5.4] add ability to define reloaded relationships #20602

wants to merge 1 commit into from

Conversation

browner12
Copy link
Contributor

Ran into this issue when using Laravel Echo to listen for some broadcast events.

currently when a Model is added to a queue and serialized, the
relationships of the Model are not restored when the Model is
unserialized/refetched from the database.

When you are handling the queued event/job with PHP, it’s not a big
issue. You can either manually load the relationships, or just use them
and they will be fetched when needed.

However, when you are broadcasting the events and listening for them in
Javascript, currently there is no way reload the relationship. This
addition allows us to define which relationships we would like to be
reloaded when the object is unserialized.

Simply add a reloadedRelationships property to your event or job:

class OrderCreated implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    /**
     * @var array
     */
    private $reloadRelationships = [
        'order' => ['user', 'lines'],
    ];

   /**
     * @var \App\Order
     */
    public $order;

This will automatically reload the user and lines relationships on the events order property.

This syntax allows us to reload relationships on multiple models, if multiple models exist on the event/job.

I don't really love the name I came up with. Would love some suggestions on it.

currently when a Model is added to a queue and serialized, the
relationships of the Model are not restored when the Model is
unserialized/refetched from the database.

When you are handling the queued event/job with PHP, it’s not a big
issue. You can either manually load the relationships, or just use them
and they will be fetched when needed.

However, when you are broadcasting the events and listening for them in
Javascript, currently there is no way reload the relationship.  This
addition allows us to define which relationships we would like to be
reloaded when the object is unserialized.
@taylorotwell
Copy link
Member

In your event constructor could you just do $this->order->load().

@browner12
Copy link
Contributor Author

I have tried both passing in the Order to the event, and loading the Order relationships in the constructor. Neither seems to work.

Based off of this paragraph in the documentation,

If your queued job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the queue system will automatically re-retrieve the full model instance from the database.

it looks like it doesn't matter what I do before the model is serialized, because it just refetches after it unserializes the model.

another option I was considering was to look for the loaded relationships on the Model, and then also serialize those a similar way where we store the ID of the related model. this seemed like the simpler solution.

@taylorotwell
Copy link
Member

The event has to be unserialized though when "BroadcastEvent" fires which would unserialize the model identifier and pass a real model back into your constructor again so I really think calling ->load() in constructor of the event would work. Can you share the full code where you do that?

@tillkruss tillkruss changed the title add ability to define reloaded relationships [5.4] add ability to define reloaded relationships Aug 19, 2017
@taylorotwell
Copy link
Member

I think we need to just make this work more transparently. I don't like having a property for it. We may just want all serialized models to reload their loaded relationships? Not sure. @themsaid

@themsaid
Copy link
Member

@taylorotwell yes reloading by default seems more reasonable as you'd expect the object you pass to have the same state.

@browner12
Copy link
Contributor Author

sorry for the delay on responding to this, was trying to work my way through the process and see where it actually loses the reloaded relationships. You are right, but it makes the new BroadcastEvent it will actually recreate the event, and we could force a reload there, but the issue happens when it then gets thrown onto the queue.

I think you are right, we should expect the state to be identical when we put it into a queue, as when we pull it out, so including the relationships (or more likely an ID) is a nicer way to go.

Would you guys like me to take a stab at this one, or are you guys gonna work on it internally?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants