2015-05-29 2 views
8

У меня есть 3 стола: company < ->users < ->invoice.Laravel 5 hasManyThore

Компания hasMany пользователей.

Пользователь belongsTo компания и, и пользователь hasMany фактуры.

Счет belongsTo пользователь.

Теперь у меня есть счет-фактура с информацией о пользователе (клиента), и я хочу, чтобы пользователь его информацию о компании, так что я сделал:

счета-фактуры hasManyThrough пользователей, компания (так получает компанию через пользователь)

Теперь это не работает, поскольку это необходимо.

Модель:

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

Счет контроллер:

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

д.Д. ($ счетов) даст может быть предоставлена ​​BadMethodCallException Call to undefined method Illuminate\Database\Query\Builder::company()

Дальнейших необходимой информация!

ответ

4

Допустим, мы имеем таблицу А и В и С где таблицей А имеет много B (OneToMany) и B имеют много C (OneToMany) симметричный доступ к таблице C из таблицы А вы можете использовать ярлык Laravel (HasManyThrough) на столе, и проблема решена

НО Если вы имеете таблицу а и в и с , где таблица а имеет много B (OneToMany) и B имеет много C (ManyToMany) вас не может использовать ярлык laravel (HasManyThrough) для доступа к таблице C из таблицы A, {из-за сводной таблицы в середине между B и C} то, что вы можете сделать в этом случае, очень просто:

В этом примере таблица A будет [курсы], таблица B будет [главы], а таблица C будет [видео] , где у каждого курса есть главы, а глава может принадлежать только одному курсу. с другой стороны, каждая глава имеет много видеороликов, в то время как видео может принадлежать многим главам.

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

Должен ли я использовать области запроса или просто отношения? – Liam

+0

@Synyster вам не нужно использовать области, но они очень рекомендуются, так как без них вы будете повторять этот мир кода везде, где вы его используете.Однако самая важная область в этом примере, если «scopeWithChaptersAndVideos», если вы хотите иметь свои результаты без использования области, должна будет написать свой контент и заменить «withVideos» содержимым этой области, а также из модели видео. –

1

Вы также можете сделать это в классе курс, поэтому при использовании -> с ('главы'), он автоматически загружает видео тоже:

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

Спустя годы это мое решение. Путь проще! – udog