灯塔嵌套突变FK字段未填写

时间:2020-04-12 15:41:24

标签: graphql laravel-lighthouse

我遇到了一些问题,围绕着Lighthouse的嵌套突变。

我有两个相关的模型:Ams\Account hasMany Ams\Contact。这是Ams\Contact模型:

namespace App\Models\Ams;

use Eloquent as Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Contact extends Model
{
    use SoftDeletes;

    public $table = 'ams_contacts';

    protected $dates = ['deleted_at'];

    public $fillable = [
        'ams_account_id',
        'forename',
        'surname',
        'active',
        'email'
    ];

    protected $casts = [
        'forename' => 'string',
        'surname' => 'string',
        'active' => 'boolean',
        'email' => 'string'
    ];

    public static $rules = [
        'ams_account_id' => 'required',
        'forename' => 'required',
        'surname' => 'required',
        'email' => 'required|email'
    ];

    public function amsAccount(): BelongsTo
    {
        return $this->belongsTo(\App\Models\Ams\Account::class, 'ams_account_id', 'id');
    }

}

我的GraphQL模式文件如下:

"A datetime string with format `Y-m-d H:i:s`, e.g. `2018-01-01 13:00:00`."
scalar DateTime @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\DateTime")

"A date string with format `Y-m-d`, e.g. `2011-05-23`."
scalar Date @scalar(class: "Nuwave\\Lighthouse\\Schema\\Types\\Scalars\\Date")

type Query {
    amsAccounts: [AmsAccount!]! @paginate(defaultCount: 10 model: "App\\Models\\Ams\\Account")
    amsAccount(id: ID @globalId): AmsAccount @find(model: "App\\Models\\Ams\\Account")

    amsContacts: [AmsContact!]! @paginate(defaultCount: 10 model: "App\\Models\\Ams\\Contact")
    amsContact(id: ID @globalId): AmsContact @find(model: "App\\Models\\Ams\\Contact")
}

type Mutation {
    createAmsAccount(
        input: CreateAmsAccountInput! @spread
    ): AmsAccount @create(model: "App\\Models\\Ams\\Account")

    updateAmsAccount(
        input: UpdateAmsAccountInput! @spread
    ): AmsAccount @update(model: "App\\Models\\Ams\\Account")

    deleteAmsAccount(
        id: ID! @rules(apply: ["required"])
    ): AmsAccount @delete(model: "App\\Models\\Ams\\Account")

    createAmsContact(
        input: CreateAmsContactInput! @spread
    ): AmsContact @create(model: "App\\Models\\Ams\\Contact")

    updateAmsContact(
        input: UpdateAmsContactInput! @spread
    ): AmsContact @update(model: "App\\Models\\Ams\\Contact")

    deleteAmsContact(
        id: ID! @rules(apply: ["required"])
    ): AmsContact @delete(model: "App\\Models\\Ams\\Contact")
}

type AmsAccount @node(namespace: "App\\Models\\Ams\\Account") {
    id: ID! @globalId
    name: String!
    url: String
    telephone: String!
    created_at: DateTime!
    updated_at: DateTime!
}

input CreateAmsAccountInput {
    name: String!
    url: String
    telephone: String!
}

input UpdateAmsAccountInput {
    id: ID!
    name: String!
    url: String
    telephone: String!
}

input UpsertAmsAccountInput {
    id: ID!
    name: String!
    url: String
    telephone: String!
}

type AmsContact @node(namespace: "App\\Models\\Ams\\Contact") {
    id: ID! @globalId
    forename: String!
    surname: String!
    active: Boolean
    email: String!
    amsAccount: AmsAccount! @belongsTo
    created_at: DateTime!
    updated_at: DateTime!
}

input CreateAmsContactInput {
    forename: String!
    surname: String!
    active: Boolean
    email: String!
    amsAccount: CreateAmsAccountBelongsTo
}

input UpdateAmsContactInput {
    id: ID!
    forename: String!
    surname: String!
    active: Boolean
    email: String!
    amsAccount: UpdateAmsAccountBelongsTo
}

input UpsertAmsContactInput {
    id: ID!
    forename: String!
    surname: String!
    active: Boolean
    email: String!
    amsAccount: UpsertAmsAccountBelongsTo
}

input CreateAmsAccountBelongsTo {
    connect: ID
    create: CreateAmsAccountInput
    update: UpdateAmsAccountInput
    upsert: UpsertAmsAccountInput
}

input UpdateAmsAccountBelongsTo {
    connect: ID
    create: CreateAmsAccountInput
    update: UpdateAmsAccountInput
    upsert: UpsertAmsAccountInput
    disconnect: Boolean
    delete: Boolean
}

input UpsertAmsAccountBelongsTo {
    connect: ID
    create: CreateAmsAccountInput
    update: UpdateAmsAccountInput
    upsert: UpsertAmsAccountInput
    disconnect: Boolean
    delete: Boolean
}

当我尝试在操场上进行以下修改时:

mutation {
  createAmsContact(
    input: {
      forename: "Jane"
      surname: "Doe"
      active: true
      email: "jd@example.com"
      amsAccount: {
        connect: 1
      }
    }
  ) {
    id
    forename
    surname
    amsAccount: id
  }
}

我收到有关以下错误消息的错误:

"debugMessage": "SQLSTATE[HY000]: General error: 1364 Field 'ams_account_id' doesn't have a default value (SQL: insert into `ams_contacts` (`forename`, `surname`, `active`, `email`, `updated_at`, `created_at`) values (Jane, Doe, 1, jd@example.com, 2020-04-12 15:31:52, 2020-04-12 15:31:52))"

我已经在网络上尝试了许多修复和建议,据我所知,我的模式遵循了文档中定义的格式,但是我无法弄清为什么它不起作用。

我也已经确认该帐户的简单突变可以正常工作。当我尝试与联系人同时创建新帐户时,也会收到类似的错误消息。

我的倾向是与不同模型的名称空间有关,但是我无法想象我是第一个有此要求的人,也找不到关于如何克服此问题的参考。

任何人和所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

因此,我的命名空间问题实际上离标记还不到一百万英里。

问题出在模型文件上,特别是在这里:

public function amsAccount(): BelongsTo
    {
        return $this->belongsTo(\App\Models\Ams\Account::class, 'ams_account_id', 'id');
    }

问题在于,在模型类开始时的BelongsTo子句中未指定use。因此,无法正确检测到返回类类型。

因此,有必要在文件顶部的use子句中添加以下内容:

use Illuminate\Database\Eloquent\Relations\BelongsTo;

这适用于其他关系类型。

这是Documentation所陈述的内容,但它是如此的细微以至于没有被点击。

RTFM。

感谢所有看过的人,并希望这对以后的人有所帮助。