2015-05-29 21 views
8

Ho 3 tabelle: company < ->users < ->invoice.Laravel 5 hasManyThrough

A società hasMany utenti.

Un utente belongsTo una società e, e un utente hasMany fatture.

Una fattura belongsTo un utente.

Ora ho una fattura con informazioni su utente (cliente), e voglio ottenere l'utente le sue informazioni sulla società così ho fatto un:

Una fattura hasManyThrough utenti, società (così ottiene la società attraverso utente)

Ora non funziona come è necessario.

Modelli:

class Company extends Eloquent { 

    protected $table = 'companies'; 

    public function users() 
    { 
     return $this->hasMany('App\User', 'id'); 
    } 

    public function invoices() 
    { 
     return $this->hasManyThrough('App\Company', 'App\User'); 
    } 
} 

class User extends Model { 

    protected $table = 'users'; 

    public function usertype() 
    { 
     return $this->belongsTo('App\UserType','usertype_id','id'); 
    } 

    public function company() 
    { 
     return $this->belongsTo('App\Company','company_id','id'); 
    } 

    public function invoice() 
    { 
     return $this->hasMany('App\Invoice'); 
    } 

} 

class Invoice extends Model { 

    protected $table = 'invoices'; 

    public function users() { 
     return $this->belongsTo('App\User', 'id'); 
    } 
} 

controller Fattura:

class InvoiceController extends Controller { 

    private $invoice; 

    public function __construct(Invoice $invoice) 
    { 
     $this->invoice = $invoice; 
    } 

    public function index(Invoice $invoice) 
    { 
     $invoices = $invoice->with('users', 'company')->get(); 

     dd($invoices); 

     return view('invoice.index', compact('invoices')); 
    } 

    public function create() 
    { 
     // 
    } 

    public function store() 
    { 

    } 

    public function show($id) 
    { 
     $invoice = Invoice::with('users')->find($id); 

     return view('invoice.show', compact('invoice')); 
    } 

    public function edit($id) 
    { 
     // 
    } 

    public function update($id) 
    { 
     // 
    } 

    public function destroy($id) 
    { 
     // 
    } 
} 

Il dd ($ fatture) daranno informazioni BadMethodCallException Call to undefined method Illuminate\Database\Query\Builder::company()

Ogni ulteriore necessaria può essere fornito!

risposta

4

Diciamo che abbiamo tabella A e B e C dove tabella A ha molti di B (OneToMany) e B ha molte delle C (OneToMany) inorder per accedere alla tabella C dalla tabella A è possibile utilizzare la scorciatoia laravel (HasManyThrough) sulla tabella A e il problema è risolto

MA Se avete tabella A e B e C dove tabella A ha molti di B (OneToMany) e B ha molte delle C (ManyToMany) voi non è possibile utilizzare la scorciatoia di laravel (HasManyThrough) per accedere alla tabella C dalla tabella A, {a causa della tabella pivot nel mezzo tra B e C} ciò che si può fare in questo caso è molto semplice:

In questo esempio, la tabella A sarà [corsi], la tabella B sarà [i capitoli] e la tabella C sarà [video] dove ogni corso può contenere capitoli, mentre un capitolo può appartenere a un solo corso. d'altra parte ogni capitolo ha molti video mentre un video può appartenere a molti capitoli.

<?php namespace Moubarmij\Models; 

use Eloquent; 

class Video extends Eloquent{ 

    protected $table = 'videos'; 

    /************************************************************* 
    * Query Scopes 
    **************************************************************/ 

    public function scopePublished($query) 
    { 
     return $query->where('published', '=', '1'); 
    } 

    public function scopeOrdered($query) 
    { 
     return $query->orderBy('order_number', 'ASC'); 
    } 

    /************************************************************* 
    * Relations 
    **************************************************************/ 

    public function chapters() 
    { 
     return $this->belongsToMany('Moubarmij\Models\Chapter', 'chapters_videos'); 
    } 


} 

<?php namespace Moubarmij\Models; 

use Eloquent; 

class Chapter extends Eloquent{ 

    protected $table = 'chapters'; 

    /************************************************************* 
    * Query Scopes 
    **************************************************************/ 

    public function scopePublished($query) 
    { 
     return $query->where('published', '=', '1'); 
    } 

    public function scopeOrdered($query) 
    { 
     return $query->orderBy('order_number', 'ASC'); 
    } 

    public function scopeWithVideos($query) 
    { 
     return $query->with(['videos' => function($q) 
     { 
      $q->ordered(); 
     }]); 
    } 


    /************************************************************* 
    * Relations 
    **************************************************************/ 

    public function course() 
    { 
     return $this->belongsTo('Course'); 
    } 

    public function videos() 
    { 
     return $this->belongsToMany('Moubarmij\Models\Video', 'chapters_videos'); 
    } 

} 

<?php namespace Moubarmij\Models; 

use Eloquent; 

class Course extends Eloquent{ 

    protected $table = 'courses'; 

    /************************************************************* 
    * Query Scopes 
    **************************************************************/ 

    public function scopeVisible($query) 
    { 
     return $query->where('visible', '=', '1'); 
    } 

    public function scopeOrdered($query) 
    { 
     return $query->orderBy('order_number', 'ASC'); 
    } 

    public function scopeWithChapters($query) 
    { 
     return $query->with(['chapters' => function($q) 
     { 
      $q->ordered(); 
     }]); 
    } 

    public function scopeWithChaptersAndVideos($query) 
    { 
     return $query->with(['chapters' => function($q) 
     { 
      $q->ordered()->withVideos(); 
     }]); 
    } 


    /************************************************************* 
    * Relations 
    **************************************************************/ 

    public function chapters() 
    { 
     return $this->hasMany('Moubarmij\Models\Chapter'); 
    } 


} 
+0

Devo utilizzare anche gli ambiti di query o solo le relazioni? – Liam

+0

@Synyster non è necessario utilizzare gli ambiti ma sono molto raccomandati, dal momento che senza di essi si ripeterà questa pace di codice ovunque venga utilizzata.Tuttavia lo scope più importante in questo esempio se 'scopeWithChaptersAndVideos' se si desidera avere i suoi risultati senza usare l'scope dovrà scrivere il suo contenuto e sostituire' withVideos 'con il contenuto di tale scope e anche dal modello video. –

1

È anche possibile fare questo nella classe del corso, in modo che quando si utilizza -> con ('capitoli'), si carica automaticamente il video troppo:

public function chapters() 
{ 
    return $this->hasMany('Moubarmij\Models\Chapter')->with('videos'); 
} 
+0

Anni dopo, questa è la mia soluzione ideale. Più semplice! – udog