skip to Main Content

I have

class People extends Model {
     public function invoices() {
          return $this->hasMany(Invoice::class)->orderBy('date', 'desc');
     }
}
...
class Invoice extends Model {
    public function person() {
          return $this->belongsTo(People::class, 'people_id');
    }
    public function latestInvoice(){
        return $this->hasOne(Invoice::class)->latestOfMany();
    }
}
...
class Clerk extends Model { 
    public function people() {
        return $this->hasMany(People::class)->orderBy('Nachname', 'desc');
    }
}

I’m trying to retrieve the latest Invoice for a Clerk and display it in the clerk.index.blade.

I hope that is not confusing.

In other words I’m trying to find the last() or first() of a not directly related or 2nd hand relationship.

What I tried:

class Clerk extends Model {    
    public function lastBill(){
        $people = $this->people()->get();
        $c = collect();
        foreach($people as $person){
            $c->add($person->latestInvoice);
        }
        $c->sortBy('date');
        return $c->first()->date;
    }
}

^This, although it works, is totally hopeless and slow, and probably very stupid.

How do I set up my relationships properly.

Or maybe I can do a raw query with select and join?

Any help appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    I only need the single most recent invoice date, so I ended up with this:

    public function latestInvoice() {
        $invoice = $this->hasOneThrough(Invoice::class, People::class)->orderBy('id', 'desc')->first();
        return $invoice;
    }
    public function latestInvoiceDate(){
        $invoice = $this->latestInvoice();
        $date = isset($invoice->date) ? $invoice->date->isoFormat('DD.MM.Y') : '';
        return $date;
    }
    

    sorting by id is faster than by date, and it's the same result... Thank you very much for your help.


  2. You can use hasOneThrough relationship:

    class Clerk extends Model {    
        public function latestInvoice(){
          return $this->hasOneThrough(Invoice::class, People::class)->orderByDesc('date');
        }
    }
    

    Then, you can do something like:

    Clerk::with('latestInvoice')->paginate();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search