我有users
表,每个用户都可以拥有很多技能:
$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()
?
答案 0 :(得分:1)
如果我正确理解您的问题,您可以加载多个关系
App\User::with('skill', 'country', 'color')->first();
以下是修补程序中的示例输出
=> App\User {#666
id: "1",
name: "Gussie Rice DVM",
email: "delfina.treutel@example.org",
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();
<强>更新强>
正如我在问题中所说,我只想在我的控制器中使用它们,所以我不想在用户模型中创建关系函数。 (我必须这样做吗?)......
<强> TL; DR 强>
在这种特殊情况下,您尝试做的事情并没有多大意义,因为它更加冗长,不那么明显,更容易出错,难以维持而不是<强大的>雄辩的惯用法方式,这是User
模型中的两个超短非常清晰的关系函数,然后是控制器中的一个单行程序,用于获取用户并加载所有三个关系。
长篇解释
只要在结果集中消除列名歧义,使用with
和连接就完全没问题。否则,在创建模型实例时,最右边的非空值将覆盖具有相同名称的列的值。为了澄清你加入三个表(用户 - &gt;公司 - &gt;颜色)并且所有表都有name
列的情况,你将获得一个名为User
的实例设置为颜色名称,如果它不是null
。
让我说明一下。如果我们运行您的查询,为了简洁我省略,我们得到以下回复
=> App\User {#871
id: "1",
name: "Tomato", // <-- color name instead of the user name
email: "walter.elyse@example.org",
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: "walter.elyse@example.org",
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个单独的查询(每个模型/表一个)。