8

I have a Score-Table with different ratings, strings and radio-buttons.

Now I want to loop through these. Normally I would go about solving it like this:

 <table>
    <tr>
        <th>ID</th>
        <th>Type</th>
        <th>Comment</th>
    </tr>
    @foreach($scores as $score)

    <tr>
        <td>{{$score->id}}</td>
        <td>{{$score->ratingradio}}</td>
        <td>{{$score->ratingtext}}</td>
    </tr>

    @endforeach
</table>

But I don't only want the order to be reversed, but I also want the array to be sliced, so that it just outputs the last 20 Elements of the array.

I attempted solving it like this in my Controller:

$scores = Score::where('unit_id', $id)->where('created_at', '>', Carbon::now()->subDays(3))->get();


// Save all ratingtexts in an array
$comments = $scores->lists('ratingtext');
$commenttype = $scores->lists('ratingradio');
// Get the last 20 Elements of the Array
$comments = array_slice($comments, -20, 20, true);
// Reverse the array, to have the latest element first displayed
$comments = array_reverse($comments, true);

And then looping through the $comments. But I don't only want to display the comment, I also want to be able to display all Information regarding this Element. So preferably like the above method with eloquent, where I output $score->ratingtext, $score->ratingradio, $score-id, and whatever I want.

I tried just using

 @foreach(array_reverse($scores) as $score)

Which obviously didn't work, because $scores is an object and it was expecting an array. How am I going to reverse loop through every score of my Scores Table?

1
  • Why don't you simply set orderBy and limit to fetch only 20 rows? Commented May 5, 2014 at 8:24

5 Answers 5

29

Retrieving the last 20 items is quite easy.

$scores = Score::where('unit_id', $id)
    ->where('created_at', '>', Carbon::now()->subDays(3))
    ->orderBy('created_at', 'desc')
    ->take(20)
    ->get();

$scores = $scores->reverse();

Done.

Just tell it to pull out the first 20 items that match your query, with a reversed order and then reverse the collection to get the proper order.

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

4 Comments

What exactly do you mean? The above will do exactly what it's supposed to do.
The problem with the above is the array key in the collection does not change and if passed using JSON, it reverts.
I'm not following @RazorMureithi, what key?
Let me try to explain what I remember the $scores variable currently has the right order if you lets say return with JSON i.e. return response()->json(['date'=>$scores]) it will revert the order. this is because the collection index did not change/
21

You can as well easily do @foreach($scores->reverse() as $score)

Comments

12

You can use:

array_reverse($scores->toArray());

or Eloquent\Collection methods to keep the Model object

$scores->reverse();

Take a look at the Eloquent\Collection API.

1 Comment

To clear it up, $scores = Score::where('unit_id', $id)->where('created_at', '>', Carbon::now()->subDays(3))->get()->reverse()->take(20) should work.
0

There are even easyest way:

$scores = Score::where('unit_id', $id)
    ->where('created_at', '>', Carbon::now()->subDays(3))
    ->orderBy('created_at', 'desc')
    ->orderBy('id', 'asc')
    ->take(20)
    ->get();

Comments

-2

Looking through the API, it seems you can use take() to make this very simple. It behaves a little differently when running on query builder vs collection, so you'd want to get your collection first.

$scores = Score::where('unit_id', $id)->where('created_at', '>', Carbon::now()->subDays(3))->get()->take(-20);

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.