Search code examples
laraveleloquentlaravel-lighthouse

How does one define a polymorphic one-to-many relation for mutations in Laravel Lighthouse?


So I've been banging my head against the wall at this question and so far I've found no solution for this.

I've created a fresh, cripsy Laravel project with the latest Lighthouse(4.12) and while I tried to follow the documentation on this I got quite lost.

So as per the docs I've made the following Schema:

type Query {
    posts: [Post!]! @paginate(defaultCount: 10)
}

type Mutation {
  createPost(input: CreatePostInput! @spread): Post @create
}

input CreatePostInput {
  title: String!
  content: String
  images: CreateImageMorphToMany
}

input CreateImageMorphToMany {
  sync: [ID!]
  connect: [ID!]
}


type User {
    id: ID!
    name: String!
    email: String!
    created_at: DateTime!
    updated_at: DateTime!
    images: Image! @morphOne
}

type Post {
    id: ID!
    title: String
    content: String
    images: [Image]! @morphMany
}

type Image {
    id: ID!
    src: String
    name: String
    imageable: Imageable @morphTo
}

union Imageable = Post | User

with the following classes:

Post model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphMany;

class Post extends Model
{

    protected $fillable = [
        'title', 'content'
    ];

    public function images(): MorphMany
    {
        return $this->morphMany('App\Image', 'imageable');
    }
}

Image model

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;

class Image extends Model
{
    public function imageable(): MorphTo
    {
        return $this->morphTo();
    }
}


And migrations:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('content');
            $table->timestamps();
        });
        // This is only here for the sake of simplicity
        Schema::create('images', function (Blueprint $table) {
            $table->id();
            $table->string('src');
            $table->string('name');
            $table->integer('imageable_id');
            $table->string('imageable_type');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
        Schema::dropIfExists('images');
    }
}

And using the provided GraphQL playground I'd expect that the following mutations:

mutation {
  createPost(input: {
    title: "asd", 
    content: "asd",
    images: {
      connect: [1]
    }

  }) {
    title
    images {
      src
    }
  }
}

Will return the connected/synced image for the created Post, but only the post is returned.

If I set the relation up manually however, and query it, everything is working correctly.

Thanks in advance!


Solution

  • Turns out, I misinterpreted the docs(what has been update since my question), as a morphone works exactly like a hasone so the correct methods are create, delete, update