yajra / laravel-datatables

jQuery DataTables API for Laravel
https://yajrabox.com/docs/laravel-datatables
MIT License
4.76k stars 859 forks source link

Sortable not working in Nested Eager Loading, 4 or more Relation #1137

Open ghost opened 7 years ago

ghost commented 7 years ago

I have a problem with yajra datatables. I`m following this

https://datatables.yajrabox.com/eloquent/relationships

But not working, if like this.

Example :

$account = People::with(['users.profile.country.state'])
Datatable::of($account)->make(true);

.....
columns : [
{name: 'users.profile.name', data: 'users.profile.name'},
{name: 'users.profile.country.state.name', data: 'users.profile.country.state.name'},
]
....

when I want to sortable users.profile.country.state.name I get error in query. "version for the right syntax to use near '.name" or "Call to a member function getRelation() on string"

thank.

UPDATE

sample (table like that):

// Table

- people :
 id
 id_user
 name

- users
 id
 username
 password

- profile
 id
 id_user
 name
 id_country

- country
 id
 name

- state
 id
 id_country
 name
yajra commented 7 years ago

Thanks for reporting. Honestly, I think I only tested this feature up to 3 nested relation.

Ping @ethaizone , @AdrienPoupa the original contributor for this feature. Thanks!

yajra commented 7 years ago

@whendy can you please state the relationship on those nested relations? Will try to reproduce the issue. Thanks!

whendy commented 7 years ago

@yajra can u see sample table, like that (just sample).

tad3j commented 7 years ago

I'm having the same problem, searching/filtering fails when doing that for more than 1 level deep relations (meaning that "account.provider.name" doesn't work, while "account.provider_id" does work for example).

...without, searching/filtering it works as expected, data is displayed.

Here is my query:

$myModel = MyModel::query()
    ->select('my_models.*')
    ->with(['account' => function ($query) {
        $query
            ->select(['id', 'account_id', 'provider_id'])
            ->with(['provider' => function ($query) {
                $query->select(['id', 'name']);
            }]);
    }]);

And my relations:

First relation:

    public function account()
    {
        return $this->belongsTo(Account::class);
    }

2nd relation:

    public function provider()
    {
        return $this->belongsTo(Provider::class);
    }

...and provider has a "name" field which I'm trying to access.

yajra commented 7 years ago

@tad3j I think the issue is on your eager load subquery. It seems like the package does not support that yet. Try using something like:

$myModel = MyModel::query()
    ->select('my_models.*')
    ->with('account.provider');
tad3j commented 7 years ago

@yajra, thanks for pushing me in the right direction. Seems like problem is related to nested with statements.

I now got it working by still using sub selects (because I don't want to expose some of the columns), but without nested with statements.

Working code looks like this now:

$myModel = MyModel::query()
    ->select('my_models.*')
    ->with(['account.provider' => function ($query) {
        $query->select(['id', 'name']);
    }]);

...sorting and filtering now works as expected.

EDIT: Tried to add another level of nesting for relations like "business.account.provider.name" - the data gets displayed but it fails on sorting/filtering with error: https://www.screencast.com/t/TUbYBH5M7vhL

For some reason code $relationship = $lastQuery->getRelation($eachRelation); returns a string which then fails in next iteration inside the same loop.

yajra commented 7 years ago

@tad3j thanks for the feedback. I was able to fix nested with on master branch yesterday but only tested it up to 3 levels (posts.user.country). Will try to do more testing but I think the patch I made yesterday will do the trick since searching is now handled by Laravel's core function orWhereHas.

This lastQuery complex code is now simplified.