nuwave / lighthouse

A framework for serving GraphQL from Laravel
https://lighthouse-php.com
MIT License
3.37k stars 438 forks source link

morphTo in mutation not syncing/connecting? #1346

Closed ghost closed 4 years ago

ghost commented 4 years ago

Describe the bug

Okay, so this might not be the best platform, but I can't seem to determine wheter this is a bug or not, so I'll give it a shot here as well.

The problem is that when I created a fresh, crispy Laravel project, added lighthouse to it then followed the documentation on polymorphic relationships, made every modifcation exactly(almost) like the docs stated, and I just couldn't make it work.

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]! @morphMany
}

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

Post Model

<?php

namespace App;

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

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();
    }
}

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')->nullable();
            $table->string('imageable_type')->nullable();
            $table->timestamps();
        });
    }

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

The mutation

mutation {
  createPost(input: {
    title: "asd2", 
    content: "asd2",
    images: {
      sync: [1]
    }

  }) {
    title
    images {
      src
    }
  }
}

Result:

{
  "data": {
    "createPost": {
      "title": "asd2",
      "images": []
    }
  }
}

Expected behavior/Solution Lighthouse connects the polymorphic relation in the given table and returns the result of the queried data.

Steps to reproduce

  1. Create a Fresh Laravel project & install lighthouse
  2. Make a polymorphic relation according to both Laravels and Lighthouses documentaion
  3. Seed the db with random comments
  4. Try to create a new post and attach one of the existing comments to it in the same(nested) mutation

Lighthouse Version 4.12

spawnia commented 4 years ago

MorphMany is equivalent to the monomorphic HasMany, so sync is not an available operation.

ghost commented 4 years ago

Dear @spawnia ,

That makes sense, but then what type of operation should I use in this case? I mean it's not like connect works either.

spawnia commented 4 years ago

create, update, upsert and delete.

ghost commented 4 years ago

Ahh I see, so I can't directly connect the two, but rather I need to manually update the relation.

Thanks a lot!