3

Is it possible to save a query bulider and use it multiple times?

for example, I have a model 'Tour'.

I create a long query buider and paginate it:

$tour = Tour::where(...)->orWhere(...)->orderBy(...)->paginate(10);

For example, 97 models qualify for the above query. "Paginate" method outputs first 10 models qualifying for the query, but I also need to so some operations on all 97 models. I don't want to 'repeat myself' writing this long query 2 times.

So I want something like:

$query = Tour::where(...)->orWhere(...)->orderBy(...);

$tour1 = $query->paginate(10); 
$tour2 = $query->get();

Is that a correct way to do in Laravel? (my version is 5.4).

1
  • Yes. It is the correct way to do it. Commented Feb 27, 2018 at 10:23

2 Answers 2

3

You need to use clone:

$query = Tour::where(...)->orWhere(...)->orderBy(...);
$query1 = clone $query;
$query2 = clone $query;

$tour1 = $query1->paginate(10); 
$tour2 = $query2->get();
Sign up to request clarification or add additional context in comments.

Comments

1

You can but it doesn't make any sense because every time a new query will be executed. So this code will work:

$query = Tour::where(...)->orWhere(...)->orderBy(...);
$tour1 = $query->paginate(10); 
$tour2 = $query->get();

But if you want to execute just one query, you'll need to use collection methods for ordering, filtering and mapping the data. You'll also need to create Paginator instance manually:

$collection = Tour::where(...)->orWhere(...)->orderBy(...)->get();
$tour1 = // Make Paginator manually.
$tour2 = $collection;
$sortedByName = $collection->sortBy('name');
$activeTours = $collection->where('active', 1);

1 Comment

I'll add how I've created paginator manually: use Illuminate\Pagination\LengthAwarePaginator as Paginator; //Get current page: $current_page = Paginator::resolveCurrentPage(); // Get items for current page (use values() method to reset the keys): $items = $collection->slice(($current_page - 1) * $paginate, $paginate)->values(); // Get Total of Items $total = $collection->count(); // PAGINATE!:) $tours = new Paginator($items, $total, $paginate, $current_page, ['path' => Paginator::resolveCurrentPath()]);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.