Including Polymorphic Parent Models in Laravel API Responses

📖 2 minutes read

Including Polymorphic Parent Models in Laravel API Responses

When building APIs with polymorphic relationships, you might run into a common pitfall: your API returns the morph pivot data (commentable_type and commentable_id) but not the actual parent model itself.

The Problem

Let’s say you have a Comment model that can belong to different types of posts (Articles, Videos, etc.) using a polymorphic relationship:

// Comment model
public function post()
{
    return $this->morphTo();
}

When you try to include the parent in your API response using ?include=post, you might only get the morph pivot columns instead of the actual post data.

The Solution

The key is ensuring your polymorphic relationship is properly defined and that the actual parent model is loaded, not just the pivot data. Here’s how:

// In your CommentController
public function index(Request $request)
{
    $query = Comment::query();
    
    // Support includes via query parameter
    if ($request->has('include')) {
        $includes = explode(',', $request->input('include'));
        
        foreach ($includes as $include) {
            if ($include === 'post') {
                // Load the actual polymorphic parent
                $query->with('post');
            }
        }
    }
    
    // Support field selection for included relations
    if ($request->has('fields')) {
        foreach ($request->input('fields', []) as $type => $fields) {
            // Apply sparse fieldsets for each included type
            if ($type === 'articles') {
                $query->with('post:id,title,slug,published_at');
            }
        }
    }
    
    return $query->get();
}

Testing Your Endpoint

Test with various combinations to ensure it works:

# Basic include
GET /api/comments?include=post

# Include with field selection
GET /api/comments?include=post&fields[articles]=title,slug

# Multiple includes
GET /api/comments?include=author,post&fields[articles]=title

Why This Matters

When the polymorphic parent isn’t properly loaded, your frontend gets incomplete data. Instead of the article title and content, you’d only see article_id and article_type – forcing additional API calls to fetch the actual data.

By loading the full parent model, your API becomes more efficient and easier to consume. This follows JSON:API conventions for sparse fieldsets and relationship includes.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *