2017-02-16 49 views
0

我正在使用Laravel 5.3並嘗試使用連接從多個表中返回數據。如何在Laravel中加入一對多關係

我使用3種型號/桌,客戶,業務和相關的網站如下:

在Customer.php:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Customer extends Model 
{ 
    public function businesses() 
    { 
    return $this->hasMany('App\Business'); 
    } 
} 

在Business.php:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Business extends Model 
{ 
    public function customer() 
    { 
    return $this->belongsTo('App\Customer'); 
    } 

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

而在Website.php中:

<?php 

namespace App; 

use Illuminate\Database\Eloquent\Model; 

class Website extends Model 
{ 
    public function business() { 
    return $this->belongsTo('App\Business'); 
    } 
} 

所以一個Customer可以有很多Businesses,它可以有很多Websites。 現在我正在嘗試使用聯合聲明來返回客戶及其相關業務和網站信息的列表。我使用下面的代碼返回這樣的信息:

$customers = \DB::table('customers') 
       ->join('businesses', 'customers.id', '=', 'businesses.customer_id') 
       ->join('websites', 'businesses.id', '=', 'websites.business_id') 
       ->select('customers.x', 'businesses.y', 'websites.z') 
       ->get(); 

而且我想數據是在關聯客戶陣列,嵌套的關聯數組,像這樣的企業和網站數據的數組返回:

[ 
    0 => { 
    $customer1Data, 
    $customer1BusinessData, 
    $customer1WebsiteData 
    } 
    1 => { 
    $customer2Data, 
    $customer2BusinessData, 
    $customer2WebsiteData 
    } 
    ... 
] 

此工作正常,如果一個客戶有一個企業它有一個網站,但假設$customer1有兩個企業,那麼上面的聯接返回的東西在這個格式:

[ 
    0 => { 
    $customer1Data, 
    $customer1BusinessData1, 
    $customer1WebsiteData 
    } 
    1 => { 
    $customer1Data, 
    $customer1BusinessData2, 
    $customer1WebsiteData 
    } 
    ... 
] 

有沒有一種方法,我可以修改加入語句返回場景格式爲:

[ 
    0 => { 
    $customer1Data, 
    businesses => { 
     $customer1BusinessData1, 
     $customer1BusinessData2 
    } 
    ... 
    } 
] 

有沒有一種方法,我可以做到這一點與加入語句?或者我應該以不同的方式來解決這個問題?任何幫助將不勝感激,非常感謝。

+0

你還沒有完全利用雄辯。你可以使用'$ customer = Customer :: with('business','business.websites') - > all()'這會加載所有的客戶,以及他們的業務和網站。所以你可以簡單地使用'$ customer-> business'來獲得所有的業務和一個嵌套的循環來獲取企業的網站。 –

回答

0

按照由@Rooshan Akthar的評論,你可以做一個下面用雄辯的,因爲關係已創建:

// Loading with relationships (i.e single query) 
Customer::with('businesses.websites'); 

// Lazy loading (i.e. multiple queries) 
Customer::find($id)->load('businesses.websites'); 

你也可以去$customer->businesses->websites;,而不必調用上述其中之一,並拉拉維爾將爲你獲得這些關係。

0

在我深入解釋雄辯的模型關係之前,請閱讀:https://laravel.com/docs/5.4/eloquent。這將清除一切。

在模型關係中,您可以指定將這兩個錶鏈接在一起的數據庫字段名稱。這甚至適用於數據透視表。基本文檔請閱讀:https://laravel.com/docs/5.4/eloquent-relationships#defining-relationships

例如在客戶模式:

public function businesses() 
{ 
    return $this->hasMany(Business::class, 'id', 'customer_id'); 
} 

public function websites() 
{ 
    //Argument order: final class, pivot class, pivot foreign key, foreign key final model, primary key start model (customer) 
    return $this->hasManyThrough(Website::class, Business::class, 'customer_id', 'id', id); 
} 

如果這最後一部分是有點難以理解,閱讀文檔:https://laravel.com/docs/5.4/eloquent-relationships#has-many-through

而對於商業模式:

public function website() 
{ 
    return $this->hasMany(Website::class, 'id', 'business_id'); 
} 

現在你可以通過使用雄辯來檢索數據。

//This will retrieve all customers with all of their website information. 
Customer::with('websites')->get(); 

//This will retrieve all customers with their business information. 
Customer::with('businesses')->get(); 

//This will retrieve all customers with business and website information 
//Retrieves: [ 
// customer: [ 
//  customerDetails: [] 
//  businesses: [ b1, b2], 
//  websites: [w1, w2] 
// ] 
//] 
Customer::with('businesses', 'websites')->get(); 

//This will retrieve all customers with business information and the website information for each business 
//Retrieves: [ 
// customer: [ 
//  customerDetails: [] 
//  businesses: [ 
//   b1: [ websites: [w1] ], 
//   b2: [ websites: [w2] ] 
//  ], 
// ] 
//] 
Customer::with('businesses.websites')->get(); 

我希望這有助於!

+0

如果將鍵值數組放入 - > get()中,則可以指定要檢索的列。不要忘記表名! –