G
G
Gautama Siddhartha2019-11-05 15:49:37
Laravel
Gautama Siddhartha, 2019-11-05 15:49:37

How to paginate complex MySQL queries in Laravel 6.x?

Good day.
I am learning Laravel. There is a task of the following plan.
I have a page with a form. The task of the form is to make a query to the database in order to get some data set from there. That is, there are 2 datetime fields (From and To), and there are a number of groups with checkmarks. Each group must have at least one check mark. As soon as we click the button, we are taken to another page that retrieves values ​​from the database based on the request. But there can be a lot of lines, up to several tens of thousands. And the logical question is pagination.
If you write not on the framework (specifically this example), then I understand how to do it. But I try on Laravel 6.x, then I start to get stupid. Data is entered into the table normally if there is no pagination. If I specify pagination, then only the first page with the required number of lines is displayed accordingly. But when going to the second page, or any other, an error occurs, since there is only 1 GET parameter 'page' in the request.
Logic suggests that you need to either cache or save the request itself somewhere, but it’s best to cache the request result and display it somehow with pagination. But judging by the documentation, everything should be simpler. Either I'm missing something, or I just don't understand the documentation. Maybe I'm just dumb.
My attempts to find the answer led to the following. The official documentation has very simple examples, from the category to display all articles on a page sorted by time. Well maybe something else has been added. But all this is not received by a GET request, but simply displayed by going to some specific page, where this data is already there. Great and mighty (Google and Yandex) also provide links to Laravel 5.2, 5.4, 5.8 versions at best. But it's pretty much the same there. There is a reference to Eloquent, but here I am completely stupid. I realized that this is working with a model. But if I understand correctly that this is necessary to set up inter-table interaction (one-to-one, one-to-many, many-to-many). But I have one table in which everything is located and I need to get filtered data from it.
I've been in a dead end for 2 weeks now, and so far I don't see a way out. I think that a similar task has already been encountered, it is unlikely that I came up with something new (the level is not the same). Please tell me where to look. Or describe the principle. I'll try to find a solution somehow.
Link to sample form:
Sample form
Sample request that is processed in the model:

The code

public function getData() {
        $request = request()->all();

        $group1 = [];
        foreach($request as $key => $value) {
            if(substr_count($key, 'gr1') > 0) {
                $group1[] = ['gr1', '=', $value];
            }
        }

        $group2 = [];
        foreach($request as $key => $value) {
            if(substr_count($key, 'gr2') > 0) {
                $group2[] = ['gr2', '=', $value];
            }
        }

        $group3 = [];
        foreach($request as $key => $value) {
            if(substr_count($key, 'gr3') > 0) {
                $group3[] = ['gr3', '=', $value];
            }
        }

        $data = DB::table('table_name')
            ->where([
                ['datetime', '>=', $request['datetimeFrom']],
                ['datetime', '<=', $request['datetimeTo']],
            ]);

        $data = $data->where(function ($query) use ($group1) {
            foreach($group1 as $item) {
                $query->orWhere($item[0], $item[1], $item[2]);
            }
        });

        $data = $data->where(function ($query) use ($group1) {
            foreach($group2 as $item) {
                $query->orWhere($item[0], $item[1], $item[2]);
            }
        });
        
        $data = $data->where(function ($query) use ($group1) {
            foreach($group2 as $item) {
                $query->orWhere($item[0], $item[1], $item[2]);
            }
        });
    }


I apologize in advance for such a long question, but still I hope for support and adequate assistance.
I hope I made my point clear. If not, then ready for constructive communication.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
K
Konstantin B., 2019-11-05
@Ya_Tuplyu

I understand that the form is sent via the GET method. When you go to another page, there are no parameters.
To do this, in the template where the pagination is displayed, you need to add the appends method

// Было
{{ $users->links() }}

// Стало
{{ $users->appends(request()->all())->links() }}

Taken from here
Two weeks is certainly too much)) Read the documentation carefully

A
Alexander Aksentiev, 2019-11-05
@Sanasol

Logic suggests that you need to either cache or save the request itself somewhere, but it’s best to cache the request result and somehow display it with pagination

And the logic doesn't tell you to make your links?
Add &page=N to your parameters and that's it.
Well, or to do your pagination completely, and no one forbids not using paginate.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question