首页 > 解决方案 > Lighthouse GraphQL - 数据透视表上的 HasManyThrough

问题描述

我有一个项目,我正在从 Rails REST API 转换为 Laravel GraphQL API(我是 Laravel 的新手),并且正在设置模型和关系。

我有一个categories,category_itemsitems表。

category_items表具有和category_id的列。item_idposition

items表有一列用于category_id

当我打开 artisan tinker 并运行App\Models\Category::find(1)->items()->get();时,它会返回所有预期的内容(包括嵌套在 Item 对象下方的数据透视表)。但是,当我在 graphql-playground 中运行它时,出现错误:

"debugMessage": "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'my_project.category_item' doesn't exist (SQL: select * from `category_item` where 0 = 1)",

我有一种感觉,我忽略了一些微小的东西,就像我不知道的错字或命名约定一样。

我还想做的是position将数据透视表中的列包含在项目对象中。本质上,不是将“位置”列嵌套在项目的枢轴内,而是希望将“位置”作为项目对象的一部分包含在内,但是我不确定这是否可能。

Schema.graphql

type Query {
    categories: [Category!]! @field(resolver: "CategoriesQuery@find_by_user")
    items: [Item!]! @field(resolver: "ItemsQuery@find_by_user")
    notifications: [Notification!]! @field(resolver: "NotificationQuery@find_by_user")
}

type Category {
    id: ID!
    name: String!
    created_at: DateTime!
    updated_at: DateTime!

    category_items: [CategoryItem!]! @hasMany
    items: [Item!]! @belongsToMany
}

type CategoryItem {
    id: ID!
    position: Int!
    created_at: DateTime!
    updated_at: DateTime!

    categories: [Category!]! @hasMany
    items: [Item!]! @hasMany
}

type Item {
    id: ID!
    name: String
    quantity: Int
    created_at: DateTime!
    updated_at: DateTime!

    categories: [Category]! @belongsToMany
    category_item: CategoryItem! @belongsTo
}

分类.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Category extends Model
{
    protected $fillable = [
        'name'
    ];

    // automatically eager load items of a category
    protected $with = ['items'];

    // define relationships
    public function category_items(): HasMany
    {
        return $this->hasMany(CategoryItem::class);
    }

    public function items(): BelongsToMany
    {
        return $this
            ->belongsToMany('App\Models\Item', 'category_items', 'item_id', 'category_id')
            ->using('App\Models\CategoryItem')
            ->withPivot(['position'])
            ->withTimestamps();
    }
}

分类项目.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Database\Eloquent\Relations\HasMany;

class CategoryItem extends Pivot
{
    protected $fillable = [
        'category_id', 'item_id', 'position'
    ];

    // public function category(): HasMany
    // {
    //     return $this->hasMany(Category::class);
    // }

    // public function item(): HasMany
    // {
    //     return $this->hasMany(Item::class);
    // }
}

项目.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Item extends Model
{
    protected $fillable = [
        'name', 'price', 'category_id', 'quantity'
    ];

    // define relationships
    public function categories(): BelongsToMany
    {
        return $this
            ->belongsToMany('App\Models\Category', 'category_items', 'item_id', 'category_id')
            ->using('App\Models\CategoryItem')
            ->withPivot(['position'])
            ->withTimestamps();
    }

    public function category_item(): BelongsTo
    {
        return $this->belongsTo('App\Models\CategoryItem');
    }
}

所以总结一下,我的问题是:

  1. 是什么导致了 Playground 中的 GraphQL 错误?
  2. 是否可以将数据透视表属性附加到其直接父对象?

标签: laraveleloquentgraphqllaravel-lighthouse

解决方案


@miken32 帮了很多忙。我删除了不必要的 CategoryItem.php 模型,将 db 表从 重命名category_itemscategory_item,并在我schema.graphql将类型重新定义为以下内容:

type Category {
    id: ID!
    name: String!
    created_at: DateTime!
    updated_at: DateTime!

    pivot: CategoryItemPivot
    items: [Item!]! @belongsToMany
}

type CategoryItemPivot {
    id: ID!
    position: Int!
    created_at: DateTime!
    updated_at: DateTime!

    categories: [Category!]! @hasMany
    items: [Item!]! @hasMany
}

type Item {
    id: ID!
    name: String
    quantity: Int
    created_at: DateTime!
    updated_at: DateTime!

    categories: [Category!]! @belongsToMany
    pivot: CategoryItemPivot
}

推荐阅读