2015-05-29 26 views
8

Tôi có 3 bảng: company < ->users < ->invoice.Laravel 5 hasManyThrough

Một công ty hasMany người dùng.

Một người dùng belongsTo một công ty và, và người dùng hasMany hóa đơn.

Hoá đơn belongsTo người dùng.

Bây giờ tôi có một hóa đơn với thông tin về người dùng (khách hàng), và tôi muốn để có được các thông tin người dùng của mình về công ty vì vậy tôi đã thực hiện một:

Hoá đơn hasManyThrough người dùng, công ty (do đó được công ty thông qua người dùng)

Hiện tại, nó không hoạt động khi cần thiết.

Models:

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'); 
    } 
} 

Invoice Bộ điều khiển:

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) 
    { 
     // 
    } 
} 

Các đ ($ hóa đơn) sẽ cung cấp một thông tin BadMethodCallException Call to undefined method Illuminate\Database\Query\Builder::company()

Bất kỳ hơn nữa cần thiết có thể được cung cấp!

Trả lời

4

Hãy nói rằng chúng tôi có bảng A và B và C nơi bảng A có nhiều trong số B (OneToMany) và B có nhiều C (OneToMany) inorder để truy cập vào bảng C từ bảng A, bạn có thể sử dụng phím tắt Laravel (HasManyThrough) trên bảng A và vấn đề được giải quyết

NHƯNG Nếu bạn có bảng A và B và C nơi bảng A có nhiều trong số B (OneToMany) và B có nhiều C (ManyToMany) bạn không thể sử dụng lối tắt của Laravel (HasManyThrough) để truy cập bảng C từ bảng A, {vì bảng tổng hợp ở giữa B và C} những gì bạn có thể làm trong trường hợp này rất đơn giản:

Trong bảng ví dụ A sẽ là [khóa], bảng B sẽ là [chương] và bảng C sẽ là [video] trong đó mỗi khóa học có thể có chương, trong khi chương chỉ có thể thuộc về một khóa học. mặt khác, mỗi chương có nhiều video trong khi một video có thể thuộc về nhiều chương.

<?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

Tôi cũng phải sử dụng phạm vi truy vấn hay chỉ quan hệ? – Liam

+0

@ Synyster bạn không cần phải sử dụng phạm vi nhưng chúng rất được khuyến khích, vì không có chúng, bạn sẽ lặp lại sự bình an mã này ở mọi nơi bạn sử dụng.Tuy nhiên, phạm vi quan trọng nhất trong ví dụ này nếu 'scopeWithChaptersAndVideos' nếu bạn muốn có kết quả của nó mà không sử dụng phạm vi sẽ phải ghi nội dung của nó và thay thế 'withVideos' bằng nội dung của phạm vi đó từ mô hình video. –

1

Bạn cũng có thể làm điều này trong các lớp học, vì vậy khi bạn sử dụng -> với ('chương'), nó sẽ tự động tải các đoạn video quá:

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

Năm sau, đây là giải pháp đi của tôi. Cách đơn giản hơn! – udog