7

I'm having issues with an array returned from DB::select(). I'm heavily using skip and take on Collections of eloquent models in my API. Unfortunately, DB::select returns an array, which obviously doesn't work with skip and take's. How would one convert arrays to a collection that can utilise these methods?

I've tried

\Illuminate\Support\Collection::make(DB::select(...));

Which doesn't quite work as I expected, as it wraps the entire array in a Collection, not the individual results.

Is it possible to convert the return from a DB::select to a 'proper' Collection that can use skip and take methods?

Update

I've also tried:

$query = \Illuminate\Support\Collection::make(DB::table('survey_responses')->join('people', 'people.id',
        '=', 'survey_responses.recipient_id')->select('survey_responses.id', 'survey_responses.response',
        'survey_responses.score', 'people.name', 'people.email')->get());

Which still tells me:

FatalErrorException in QueryHelper.php line 36:
Call to a member function skip() on array

Cheers

2 Answers 2

13

I would try:

$queryResult = DB::table('...')->get();

$collection = collect($queryResult);

If the query result is an array, the collection is filled up with your results. See the official documentation for the collection. Laravel5 Collections

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the comment. I managed that part with Collection::make(), unfortunately I'm still unable to run skip() and take() against collections.
I am not sure what you mean with skip() and take(). The Collection class dose not have such methods. Collection Can you post what you want to do with the collection?
Yes, sorry my understanding of the Collection class was limited. What I want to do is construct pagination headers manually with the skip and take methods. Unfortunately, these methods only seem to be available on the Query\Builder class. I'll have to find some other way. Thanks though.
the forpage() method is great for pagination (Taylor has thought of most use cases as usual :)
1

For anyone else that's having this sort of problem in Laravel, I figured out a work around with the following solution:

        $query = DB::table('survey_responses')->join('people', 'people.id', '=', 'survey_responses.recipient_id')
            ->select('survey_responses.id', 'survey_responses.response', 'survey_responses.score', 'people.name', 'people.email');
            if(isset($tags)){
                foreach($tags as $tag){
                    $query->orWhere('survey_responses.response', 'like', '%'.$tag.'%');
                }
            };

        // We apply the pagination headers on the complete result set - before any limiting
        $headers = \HeaderHelper::generatePaginationHeader($page, $query, 'response', $limit, $tags);
        // Now limit and create 'pages' based on passed params
        $query->offset(
            (isset($page) ? $page - 1 * (isset($limit) ? $limit : env('RESULTS_PER_PAGE', 30)) : 1)
        )
        ->take(
            (isset($limit) ? $limit : env('RESULTS_PER_PAGE', 30))
        );

Basically, I wasn't aware that you could run the queries almost incrementally, which enabled me to generate pagination chunks before limiting the data returned.

Comments

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.