Использовать поле таблицы со ссылкой в ​​качестве аргумента для схемы GraphQL в Laravel Lighthouse

Я использую nuwave / Lighthouse с Laravel для создания GraphQL API, и у меня есть две таблицы ниже

Authors
----------
id
username
name


Articles
--------
id
author_id
title

Я могу получить список статей, принадлежащих автору, author_id со схемой ниже

type Query {
    articles(author_id: Int! @eq): Article @all
 }

type Author {
    id: ID!
    username: String!
    name: String!
    articles: [Article!]! @hasMany
}

type Article {
    id: ID!
    author_id: ID!
    title: String!
    author: Author! @belongsTo
}

Запрос будет

{
    articles(author_id: 1) {
        data {
            title
        }
    }
}

У меня есть две модели Eloquent с правильно определенными отношениями.

Я не могу понять, как получить список статей по username автора. Запрос должен выглядеть следующим образом

{
    articles(username: "joebloggs") {
        data {
            title
        }
    }
}

Я предполагаю, что любой, кто не знаком с Laravel, но знает, что GraphQL все равно сможет мне помочь, обратившись к директивам Lighthouse.

2 ответа

Мне удалось заставить это работать после следования предложению от @OliverNybroe

Добавил belongsToAuthor метод к Article модель

public function belongsToAuthor($builder, $username)
{
    return $builder->where('id', 
        Author::where('username', $username)->first()->id
    );
}

Запрос в схеме выглядит так

articles(username: String! @builder (method: "App\\Article@belongsToAuthor")): [Article!]! @paginate(type: "paginator" model: "App\\Article")

В Маяке мы обычно используем eq Директива для этого, но в вашем случае вы пытаетесь сделать оператор where из поля отношений.

Вы можете сделать это с несколькими подходами, наиболее гибкий builder директива Эта директива позволяет вам модифицировать построитель запросов в методе из аргумента graphql. В методе он передает конструктор запросов и значения аргументов в качестве аргументов метода. Затем вы можете легко с помощью этого метода выполнить оператор where, который необходимо отфильтровать по имени пользователя.

Другой подход заключается в использовании where Директива вместе с clause аргумент. Тогда значение, которое вы поставите в clause аргумент будет область, которая фильтрует по имени пользователя. Эта область будет получать динамическое значение, введенное в предоставленный аргумент graphql.

Логика фильтрации будет одинаковой в обоих подходах и будет выглядеть примерно так

$articlesQuery->whereHas('author' function (Builder $query) use ($username) {
    $query->where('username', '=', $username);
});

Другие вопросы по тегам