2017-02-10 42 views
1

我有users表,每個用戶都可以有很多技能:我可以在laravel查詢構建器中將`join`和`with`放在一起嗎?

$user = User::with('Skill')->where('id',1)->first(); 

沒問題至今!我可以使用像這樣的技能:

$user->Skill->name 

還有很多其他表屬於用戶, (公司,顏色...),我只想在我的控制器中使用它們,所以我不想在用戶模型中創建關係函數

我想要的是這樣的查詢:

$user = User::with('Skill') 
      ->leftJoin('companies', function ($join) use ($id) { 
       $join->on('companies.user_id','=' ,'users.id'); 
       $join->where('users.id', '=',$id); 
      }) 
      ->leftJoin('colors', function ($join) use ($id) { 
       $join->on('colors.user_id','=' ,'users.id'); 
       $join->where('users.id', '=',$id); 
      }) 
      ->first(); 

但它給我空輪廓和沒有顏色,沒有公司$user信息!

我必須把Skill模型中加入的with()而不是嗎?

回答

1

如果我正確理解你的問題,你可以加載多個關係

App\User::with('skill', 'country', 'color')->first(); 

這裏是補鍋匠

=> App\User {#666 
    id: "1", 
    name: "Gussie Rice DVM", 
    email: "[email protected]", 
    created_at: "2017-02-10 19:09:43", 
    updated_at: "2017-02-10 19:09:43", 
    skill: App\Skill {#662 
     id: "1", 
     name: "mollitia", 
     user_id: "1", 
     created_at: "2017-02-10 19:09:43", 
     updated_at: "2017-02-10 19:09:43", 
    }, 
    country: App\Country {#667 
     id: "1", 
     name: "Sierra Leone", 
     user_id: "1", 
     created_at: "2017-02-10 19:09:43", 
     updated_at: "2017-02-10 19:09:43", 
    }, 
    color: App\Color {#669 
     id: "1", 
     name: "Brown", 
     user_id: "1", 
     created_at: "2017-02-10 19:09:43", 
     updated_at: "2017-02-10 19:09:43", 
    }, 
    } 

樣本輸出在這個例子中所有的關係都是一個對一個,但他們很容易就可以是一對多的。

App\User::with('skills', 'countries', 'colors')->first(); 

UPDATE:

正如我在想我的控制器只用一次,所以我不希望創建用戶模型的關係函數的問題時說。 (我必須這樣做嗎?)......

TL; DR

什麼你試圖做不會使一個很大的意義在這種特殊情況下,因爲它更詳細不太明顯,更容易出錯,難以維持,而不是雄辯慣用方式,這是一個User模型兩個超級短很清晰的關係的函數,然後一個班輪在獲取用戶和加載所有控制器三個關係。

長解釋

使用with並加入完全是罰款,只要你在結果集消除歧義列名。否則,在創建模型實例時,具有相同名稱的列的值將被最右邊的非空值覆蓋。爲了澄清你的情況,如果你加入三個表(用戶 - >公司 - >顏色)和所有的人都在name列,你會得到一個User實例重新設置爲顏色名稱,如果它不是null名字。

讓我來說明一下。如果我們運行查詢,我省略爲簡潔起見,我們得到以下背

=> App\User {#871 
    id: "1", 
    name: "Tomato", // <-- color name instead of the user name 
    email: "[email protected]", 
    created_at: "2017-02-10 19:34:51", 
    updated_at: "2017-02-10 19:34:51", 
    user_id: "1", 
    skill: App\Skill {#873 
     id: "1", 
     name: "tempora", 
     user_id: "1", 
     created_at: "2017-02-10 19:34:51", 
     updated_at: "2017-02-10 19:34:51", 
    }, 
    } 

瞭解如何在返回User模型你的名字設置爲顏色的名稱,而不是用戶名

你需要雄心勃勃列顯式定義名稱:

App\User::with('skill')->leftJoin('companies', function ($join) use ($id) 
    join->on('companies.user_id','=' ,'users.id'); 
    $join->on('users.id', '=',$id); 
})->leftJoin('colors', function ($join) use ($id) { 
    $join->on('colors.user_id','=' ,'users.id'); 
    $join->on('users.id', '=', $id); 
})->select(
    'users.*', 
    'companies.name as company_name', // <-- 
    'colors.name as color_name' // <-- 
)->first(); 

,這將給你

=> App\User {#885 
    id: "1", 
    name: "Kareem Mante", // <-- users.name 
    email: "[email protected]", 
    created_at: "2017-02-10 19:34:51", 
    updated_at: "2017-02-10 19:34:51", 
    company_name: "Renner Group", // <- companies.name 
    color_name: "Tomato", // <-- colors.name 
    skill: App\Skill {#887 
     id: "1", 
     name: "tempora", 
     user_id: "1", 
     created_at: "2017-02-10 19:34:51", 
     updated_at: "2017-02-10 19:34:51", 
    }, 
    } 

現在您可能想要使用連接的唯一情況是如果您返回一個較大的結果集並希望避免有4個單獨的查詢(每個模型/表一個)。

+0

謝謝@peterm!正如我在問題中所說的,我只想在控制器中使用它們,所以我不想在用戶模型中創建關係函數。 (我必須這樣做嗎?)。或者,另一種方法是:只用''連接'不用'()'我也可以用這種方式。但我不能把他們放在一起嗎? ('加入'和'加') –

+0

@AhmadMobaraki請參閱已解釋的更新答案。但總之你不想這樣做。 – peterm

相關問題