Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jpeterson579's avatar

Eager loading Polymorphic relationship. Need help

Hi all,

I have two activities (ratings, events) that go into a feed table through a polymorphic relationship. When I do

$feeds = \App\Activityfeed::with('feedable')->get(); 

It works fine, giving me 2 different types of activities and that data. However I want to pull in the related product data for my rating activity and the business data for the event activity. So I figured

$feeds = \App\Activityfeed::with('feedable.product', 'feedable.business')->get();

However this gives me an error.

Call to undefined relationship [product] on model [App\Event]

My model structure is below. What am i missing?

Modals: Businesses Modal

class Business extends Model
{
    use Taggable;

    // Fillable fields for a business
    protected $fillable = [
        'name',
        'street',
        'city',
        'state',
        'zip',
        'country',
    ];

    // A Business is owned by a user
    public function owner() {
        return $this->belongsTo('App\User', 'user_id' );
    }
    
    // A business is composed of many products
    public function products()
    {
        return $this->hasMany(Product::class);
    }
    
    // A business can have many events
    public function events()
    {
        return $this->hasMany(Event::class);
    }
}

Events

class Event extends Model
{
    // Fillable fields for a event
    protected $fillable = [
        'name',
        'day',
        'start',
        'end',
        'price',
        'description',
        'image',
    ];
    
    // An event was created by a user
    public function user()
    {
        return $this->belongsTo(User::class);
    }
    
    // An event belongs to a business
    public function createdBy()
    {
        return $this->belongsTo('App\Business');
    }
    
    // Get all of ratings activities 
    public function activityfeeds()
    {
        return $this->morphMany('App\Activityfeed', 'feedable');
    }
}

Products Modal

class Product extends Model
{
    // Fillable fields for a product
    protected $fillable = [
        'name',
        'type',
        'description',
        'img_url',
    ];
    
    // A product belongs to a business
    public function creator()
    {
        return $this->belongsTo('App\Business');
    }
    
    
    // Product has many ratings
    public function ratings()
    {
        return $this->hasMany(Rating::class);
    }
    

}

Ratings Modal

    class Rating extends Model
    {
        // Rating belongs to a user 
        public function user()
        {
            return $this->belongsTo(User::class);
        }
        
        // Rating belongs to a product
        public function product()
        {
            return $this->belongsTo(Product::class);
        }
        
        public function activityfeeds()
        {
            return $this->morphMany('App\Activityfeed', 'feedable');
        }
    }

Activityfeed

class Activityfeed extends Model
{
    protected $fillable = ['user_id'];
    
    /**
     * Get all of the owning feedable models.
     */
    public function feedable()
    {
        return $this->morphTo();
    }
}

Controller

$feeds = \App\Activityfeed::with('feedable.product', 'feedable.business')->get();
dd($feeds->toArray());
0 likes
10 replies
bastman69's avatar

try

$feeds = \App\Activityfeed::with(['feedable.product', 'feedable.business'])->get();
mikevrind's avatar

I can't say if this works in your situation, but you could use the 'with' property on your models to define the relations that should eager load on every query.

I'm using this in an application which also uses a polymorphic relation to load all kinds of related models which are unique per model.

jpeterson579's avatar

@bastman69 @mikevrind

$feeds = \App\Activityfeed::with('feedable.product', 'feedable.business')->get();

gives me

RelationNotFoundException in RelationNotFoundException.php line 20: Call to undefined relationship [product] on model [App\Event].

Its interesting because the product model has nothing to do with an event model and a rating model has nothing to do really a business model. However i want ratings and events in my activity feed along with the respective models ratings->product and events->business...

jpeterson579's avatar

Maybe there is a way to put a conditional on

$feeds = \App\Activityfeed::with('feedable.product', 'feedable.business')->get();

So that when feedable_type = App\Event it eager loads feedable.business and when feedable_type = App\Rating it eager loads feedable.product?

1 like
atorscho's avatar

You could try something like this:

Activityfeed::with(['feedable' => function (MorphTo $query) {
	$query->morphWith([
		Product::class => ['product'],
		Business::class => ['business'],
	])
})
9 likes
atorscho's avatar

@amitsolanki24_ if you are asking about the concept of polymorphic relations, I invite you to read this whole chapter in Laravel Docs.

But in sum it up: Polymorphic relations allow you to create a generic table that you could reuse with different (and multiple) tables. e.g. you could create post_comments, category_comments, product_comments tables where you repeat the same columns related to the comments. With morphTo and morphMany you can have a simple comments table that will be able to be used with any amount of models

Please or to participate in this conversation.