2017-02-10 291 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

相关问题