Coder Social home page Coder Social logo

Comments (7)

sebastiaanluca avatar sebastiaanluca commented on May 3, 2024 14

Good tip!

Remembered I had to solve this in the past too. For those interested:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;

trait GroupedLastScope
{
    /**
     * Get the latest entry for each group.
     *
     * Each group is composed of one or more columns that make a unique combination to return the
     * last entry for.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param array|null $fields A list of fields that's considered as a unique entry by the query.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLastPerGroup(Builder $query, ?array $fields = null) : Builder
    {
        return $query->whereIn('id', function (QueryBuilder $query) use ($fields) {
            return $query->from(static::getTable())
                ->selectRaw('max(`id`)')
                ->groupBy($fields ?? static::$groupedLastScopeFields);
        });
    }
}

from blog-contest-may-mayhem.

sebastiaanluca avatar sebastiaanluca commented on May 3, 2024 1

My memory's a little foggy trying to remember this use case ๐Ÿ˜… Given the example in the opening post where a users has a lot of messages and we want the last message per user:

$latest = Message::query()
    ->lastPerGroup(['user_id'])
    ->get()

Which will (should) return a list of recent messages, one per user.

If you want to be sure you're getting the latest by date instead of by auto-incremented ID, I suppose you can change max(id) to max(created_at) in the scope.

from blog-contest-may-mayhem.

sinall avatar sinall commented on May 3, 2024 1

What if the table doesn't have a id column?

from blog-contest-may-mayhem.

exSnake avatar exSnake commented on May 3, 2024

Good tip!

Remembered I had to solve this in the past too. For those interested:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;

trait GroupedLastScope
{
    /**
     * Get the latest entry for each group.
     *
     * Each group is composed of one or more columns that make a unique combination to return the
     * last entry for.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param array|null $fields A list of fields that's considered as a unique entry by the query.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLastPerGroup(Builder $query, ?array $fields = null) : Builder
    {
        return $query->whereIn('id', function (QueryBuilder $query) use ($fields) {
            return $query->from(static::getTable())
                ->selectRaw('max(`id`)')
                ->groupBy($fields ?? static::$groupedLastScopeFields);
        });
    }
}

Usage example?

from blog-contest-may-mayhem.

joefreire avatar joefreire commented on May 3, 2024

@sebastiaanluca has some exemple?

from blog-contest-may-mayhem.

eduardr10 avatar eduardr10 commented on May 3, 2024

Good tip!

Remembered I had to solve this in the past too. For those interested:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;

trait GroupedLastScope
{
    /**
     * Get the latest entry for each group.
     *
     * Each group is composed of one or more columns that make a unique combination to return the
     * last entry for.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param array|null $fields A list of fields that's considered as a unique entry by the query.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLastPerGroup(Builder $query, ?array $fields = null) : Builder
    {
        return $query->whereIn('id', function (QueryBuilder $query) use ($fields) {
            return $query->from(static::getTable())
                ->selectRaw('max(`id`)')
                ->groupBy($fields ?? static::$groupedLastScopeFields);
        });
    }
}

Where should I put this code?

I have tried to make this work and I have not been able to achieve it.

from blog-contest-may-mayhem.

exSnake avatar exSnake commented on May 3, 2024

Good tip!
Remembered I had to solve this in the past too. For those interested:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as QueryBuilder;

trait GroupedLastScope
{
    /**
     * Get the latest entry for each group.
     *
     * Each group is composed of one or more columns that make a unique combination to return the
     * last entry for.
     *
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param array|null $fields A list of fields that's considered as a unique entry by the query.
     *
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeLastPerGroup(Builder $query, ?array $fields = null) : Builder
    {
        return $query->whereIn('id', function (QueryBuilder $query) use ($fields) {
            return $query->from(static::getTable())
                ->selectRaw('max(`id`)')
                ->groupBy($fields ?? static::$groupedLastScopeFields);
        });
    }
}

Where should I put this code?

I have tried to make this work and I have not been able to achieve it.

It's a trait, in a different php file then "Use GroupedLastScope" on the top of your model

from blog-contest-may-mayhem.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.