mercredi 9 novembre 2016

Retrieve distantly related Models through "Parent" Model (Descendant Models?)

I have the following scenario with my models.

  • User has many Companies.
  • Companies have many Customers.
  • Customers have many Invoices.
  • Invoices have many Transactions.

What I am trying to achieve is that I can call those $user->customers, $user->invoices and $user->transactions on the User model. The $user->customers is working with a hasManyThrough relationship because the customers table has a company_id field which then goes to the companies table where a user_id field exists which then goes to the users table and checks for the id field. This pretty much goes like customers->companies->user which means it goes from each customer to the company and then to the company owner (user). This means I would want invoices->customers->companies->user and transactions->invoices->customers->companies->user.

Now the invoices and transactions tables don't have a user_id or company_id field which means I can't just put in a hasManyThrough as far as I know. At the moment I am retrieving the invoices and transactions one-by-one and store them in a collection that I return.

So my problem is to figure out how to backtrack from all invoices to find the Owner (User Model) which would require to go to the customer of an invoice, from the customer to the company and than from the company to the users.

invoices - customer_id (Go to the Customers table)
    customers - company_id (Continue to the Companies table)
        companies - user_id (Continue to the Users table)
            users - id (This should now return all invoices)

transactions - invoice_id (Go to the Invoices table)
    invoices - customer_id (Continue to the Customers table)
        customers - company_id (Continue to the Companies table)
            companies - user_id (Continue to the Users table)
                users - id (This should now return all transactions)

So what I want is to get all models of a certain type that are descendant from the Company Model and return an Eloquent Collection of them to be able to paginate or further process them.

Here is a Model to give you an idea of what I am doing at the moment.

<?php

namespace App;

class User extends Eloquent
{
    // Companies Table
    // - id
    // - user_id
    // ...
    public function companies()
    {
        return $this->hasMany(Company::class);
    }

    // Customers Table
    // - id
    // - company_id
    // ...
    public function customers()
    {
        return $this->hasManyThrough(Customer::class, Company::class);
    }

    // Invoices Table
    // - id
    // - customer_id
    // ...
    public function invoices()
    {
        $invoices = new collect([]);

        foreach ($this->customers as $customer) {
            $invoices = $invoices->merge($customer->invoices);
        }

        return $invoices;
    }

    // Transactions Table
    // - id
    // - invoice_id
    // ...
    public function transactions()
    {
        $transactions = collect([]);

        foreach ($this->invoices() as $invoice) {
            $transactions->push($invoice->transaction);
        }

        return $transactions;
    }
}



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire