我有两个数据库表:用户和学生。学生是用户,但有额外的数据(地址)。我的学生模型中有一个belongsTo('User')关系。
如果我现在查询学生模型:
$this->student
->with('user')
->first();
我得到了这个结果:
{
"id": 1,
"user_id": 12,
"street": "Petershof",
"house_number": "3787",
"postal_code": "8161 NM",
"city": "Tienhoven",
"user": {
"id": 12,
"email": "bvierdag@yahoo.nl",
"first_name": "Nathan",
"last_name": "van Dijk",
"name": "Nathan van Dijk"
}
}
但是,我想展平结果,以便用户字段位于父(Student)对象中。像这样:
{
"id": 1,
"user_id": 12,
"street": "Petershof",
"house_number": "3787",
"postal_code": "8161 NM",
"city": "Tienhoven",
"email": "bvierdag@yahoo.nl", // = user field
"first_name": "Nathan", // = user field
"last_name": "van Dijk", // = user field
"name": "Nathan van Dijk" // = user field
}
我曾尝试使用leftJoin('users','user_id','=','users.id')而不是with(),但后来我丢失了我的虚拟属性'name'(在User模型中定义) )并且也不能再查询用户的关系。
我怎样才能以干净的方式实现这一目标?
答案 0 :(得分:0)
$this->student
->leftJoin('users', 'users.id', '=', 'students.user_id')
->select(
'students.*',
'users.email',
'users.first_name',
'users.last_name',
DB::raw("concat(users.first_name, ' ', users.last_name) as name"),
)->first();
在这种情况下,您可以将表格放在像users.email
这样的选项中。
这些关系的工作方式是一样的,我想问题只是覆盖了students
id与users
id,如果你没有指定select
并抓住所有字段。
答案 1 :(得分:0)
老问题,但这里有。
阅读你的评论似乎你想为此做一个api。如果它只是一个端点格式化动态结果不应该是一个问题,但是对于更多的端点我会建议变换器模式。
这可以通过让一个单独的类根据您的db数据返回一个数组来实现。然后你拿走那个数组并在你的response()
中使用它。
因此,在您的控制器中,您可以执行return response(Student::all());
之类的操作,而不是执行return response(StudentTransformer::transform(Student::all()))
之类的操作。
此处的优点是您只有一个文件夹(Transformers
)来检查响应数据格式。缺点是当您的数据库发生变化时,您还需要更新变压器。