skip to Main Content

how can I sort by related column in laravel lighthouse graphql?

For example, I have Products that have One Category but I can’t SortBy Category. How can I do that?

GraphQL

getProducts(orderBy: _ @orderBy): [Product!]! @all

type Product {
    id: ID
    code: String
    article: String

    category: Category
}
type Category {
    id: ID
    name: String
    products: [Product]
}

My Models where you can see the relationship between Products and Categories

class Product extends Model
{
    ...
    public function category()
    {
        return $this->belongsTo(Category::class);
    }
}


class Category extends Model
{
    ...
    public function products()
    {
        return $this->hasMany(Product::class);
    }
}

SOLUTION

Create a Builder

<?php

namespace AppGraphQLQueries;

use IlluminateDatabaseEloquentBuilder;

class ProductBuilder
{
    public function getProducts(Builder $builder)
    {
        return
            $builder->join('categories', 'categories.id', '=', 'products.category_id');
    }
}

Then add the builder to schema.graphql

getProducts(orderBy: _ @orderBy): [Product!]!
    @all
    @builder(method: "App\GraphQL\Queries\ProductBuilder@getProducts")

Now you can call and order by relationship

{
    getProducts(orderBy: {column: "categories.name", order: ASC}){
        id
        code
        article
        category {
            name
       }
   }
}

2

Answers


  1. I think the query variable part is not correct. Check this:

    {"orderBy":
        [
            {"category": 
                {"aggregate": "MAX", "column": "name"}, 
                "order": "ASC"
            },
            {"category": 
                {"aggregate": "COUNT"}, 
                "order": "ASC"
            }
        ]
    }
    
    Login or Signup to reply.
  2. If:

    • Product belongs to one Category
    • Category has many Products

    Then Category class should look something like this:

    class Category extends Model
    {
       ....
    
       public function products(): HasMany
       {
        return $this->hasMany(Product::class, <id_field_in_category_table>, <category_field_name_in_products_table>);
       }
    
    }
    

    And Product class should resemble this:

    class Product extends Model
    {
    
        ...
    
        public function category(): BelongsTo
        {
            return $this->belongsTo(Category::class, <category_field_name_in_products_table>, <id_field_in_category_table> );
        }
    
    }
    

    2 )Then add following to your schema.graphql.php

    
    input QueryGetProductsOrderByOrderByClause {
        "The column that is used for ordering."
        column: QueryGetProductsOrderByColumn!
    
        "The direction that is used for ordering."
        order: SortOrder!
    }
    
    "Allowed column names for Query.posts.orderBy"
    enum QueryGetProductsOrderByColumn {
        CATEGORY @enum(value: "category.name")
    }
    
    "Directions for ordering a list of records."
    enum SortOrder {
        "Sort records in ascending order."
        ASC
    
        "Sort records in descending order."
        DESC
    }
    
    
    1. Update Product and Category:
    
    type Product {
        id: ID
        code: String
        article: String
    
        category: Category! @belongsTo
    }
    
    type Category {
        id: ID
        name: String
        products: [Product] @hasMany
    }
       
    
    1. Update query
    
    Query {
        getProducts(orderBy: _ @orderBy(columns: ["category"])): [Product!]! @all
    }
       
    

    There was an error in my first post, it should be: @orderBy(columns: ["category"]).

    Then you should be able to query:

    
    
    {
        getProducts(orderBy: [{ column: CATEGORY, order: ASC }]){
            id
            code
            article
            category {
                name
           }
       }
    }
       
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search