laravel / framework

The Laravel Framework.
https://laravel.com
MIT License
32.62k stars 11.03k forks source link

Support ObservedBy on parent model classes #53579

Closed adamthehutt closed 2 days ago

adamthehutt commented 2 days ago

When an Eloquent model extends another Eloquent model, the check for the ObservedBy attribute only considers the class itself. Any observers registered in the parent model are ignored.

This change adds support for the ObservedBy attribute in parent classes and traverses the hierarchy until the top Model class is reached.

github-actions[bot] commented 2 days ago

Thanks for submitting a PR!

Note that draft PR's are not reviewed. If you would like a review, please mark your pull request as ready for review in the GitHub user interface.

Pull requests that are abandoned in draft may be closed due to inactivity.

taylorotwell commented 2 days ago

Hey there! Could we get a test for this? Also should it keep going back up the tree in case there are multiple extensions?

adamthehutt commented 2 days ago

@taylorotwell You're too fast! :) I added another couple of commits after the initial draft pull request. These address the tree traversal issue you're asking about.

Will add a test ASAP.

adamthehutt commented 2 days ago

@taylorotwell Added a test. (Sorry about the sloppy commit history.)

taylorotwell commented 2 days ago

Thanks!

patrickomeara commented 1 hour ago

This is a breaking change for me as I have a parent observer that creates polymorphic relationships, the grandchild model can't have these and doesn't have a morph map value.

Here is another example:

class MessageObserver
{
    public function created(Message $message) 
    {
        // send to all users
    }
}

#[ObservedBy(MessageObserver)]
class Message extends Model {}

class AdminMessage extends Message {}

Previously, creating an AdminMessage wouldn't send a notification to all users, now it is.

This PR takes away the granularity of adding the ObservedBy attribute where it's needed and assumes it can run for all child models.

Should we check for instanceOf in the observer methods?