Laravel-json-api: Is there any way to sort by a mutator attribute?

Created on 4 Oct 2019  路  6Comments  路  Source: cloudcreativity/laravel-json-api

Say in a model you add something like:

    public function getTotalAttribute( int $id ) {
        return DifferentModel::where( 'client_id', $id )->count();
    }

and in your Resource/Schema.php

    public function getAttributes( $resource ) {
        return [
            'total' => $resource->Total,
        ];
    }

This properly displays the value, but is there any way to make this a sortable attribute?

Give in the SortModels.php trait, ordering is done by the query Builder, but Laravel doesn't seem to let you sort by custom mutator attributes unless it's a collection (using SortBy())

    protected function sortBy($query, SortParameterInterface $param)
    {
        $column = $this->getQualifiedSortColumn($query, $param->getField());
        $order = $param->isAscending() ? 'asc' : 'desc';

        $query->orderBy($column, $order);
    }

Any way to accomplish this? Unfortunately unable to modify this database.

Thanks!

question

All 6 comments

You'd need to sort it after the database has been queried, i.e. sort the collection. You'd need to overload the method that returns the collection, and sort it before returning it.

Hey Chris,

Thanks for the reply. Would you mind pointing me to the class/method that returns the collection?

Appreciate this great package and the support.

queryAll() on your Eloquent adapter:
https://github.com/cloudcreativity/laravel-json-api/blob/develop/src/Eloquent/AbstractAdapter.php#L636

You are going to have problems though... for example, if the client sends page parameters, then there's no way to honour the request because you'd need to sort before retrieving the page from the database, which is not possible to do.

So basically implementing this is not going to be straightforward, and would only really work if you're retrieving all of the records from the database, and then sorting them before returning them to the client.

But worth saying, it would be exactly the same problem if you were trying to list the records in a Blade template and wanting to sort them by the computed attribute... i.e. this isn't a problem with the API implementation, it's to do with wanting to sort on an attribute that you're computing after pulling records out of the database.

Hi Chris,

Thanks again for the reply. I was worried you'd say that but very happy that you did.

I'll try to approach this from the Adapter::filter() method then and see if I can get this going with some SQL instead.

Great - I'll close this issue for now then as it looks like your questions are answered!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dklesev picture dklesev  路  4Comments

pro-cms picture pro-cms  路  5Comments

JeanLucEsser picture JeanLucEsser  路  6Comments

GregPeden picture GregPeden  路  4Comments

lindyhopchris picture lindyhopchris  路  6Comments