amrnn90 / laravel-cursor-paginator

Cursor pagination for Laravel
MIT License
18 stars 6 forks source link

Duplicate column name 'id' in combination with hasManyThrough() #19

Open janboddez opened 3 years ago

janboddez commented 3 years ago

I'm seeing this SQL error:

Column already exists: 1060 Duplicate column name 'id' (SQL: select * from (select * from `entries` inner join `feeds` on `feeds`.`id` = `entries`.`feed_id` where `feeds`.`category_id` = 2 and `entries`.`deleted_at` is null and `entries`.`user_id` = 1) as `` order by `published` desc, `id` desc limit 16)

I'm thinking the empty as `` might have something to do with it?

Happens when I do:

        $entries = $category->entries() // Does not work with `cursorPaginate`.
            ->orderBy('published', 'desc')
            ->orderBy('id', 'desc')
            ->with('feed')
            ->cursorPaginate();

Where Category has a hasManyThrough relationship with Entry, through Feed (the intermediate model). I.e., an entry belongs to one feed which belongs to one category.

Does not happen when I explicitly do this (i.e., use a whereHas condition):

        $entries = Entry::orderBy('published', 'desc')
            ->orderBy('id', 'desc')
            ->whereHas('feed', function ($query) use ($category) {
                $query->where('category_id', $category->id);
            })
            ->with('feed')
            ->cursorPaginate();

According to Debug bar, the following SQL is generated for this last bit of code:

select * from (select * from `entries` where exists (select * from `feeds` where `entries`.`feed_id` = `feeds`.`id` and `category_id` = 2 and `feeds`.`user_id` = 1) and `entries`.`deleted_at` is null and `entries`.`user_id` = 1) as `` order by `published` desc, `id` desc limit 16

select * from `feeds` where `feeds`.`id` in (3, 4, 7, 17, 23, 28, 159, 178) and `feeds`.`user_id` = 1

So no JOIN, it seems.

(The user_id = 1 is because of a global scope.)

janboddez commented 3 years ago

Note that I can do the following (based on a regular hasMany relationship between Feed and Entry) just fine:

$entries = $feed->entries()
            ->orderBy('published', 'desc')
            ->orderBy('id', 'desc')
            ->with('feed')
            ->cursorPaginate();
janboddez commented 3 years ago

Stumbled upon https://github.com/yajra/laravel-datatables/issues/2462#issuecomment-701127051, and it seems adding select('entries.*') to the original code indeed makes it works, too. (No idea why, though.)