Laravel 5离开了加入关系

时间:2015-01-20 17:44:15

标签: php laravel

我有两个数据库表:用户和学生。学生是用户,但有额外的数据(地址)。我的学生模型中有一个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模型中定义) )并且也不能再查询用户的关系。

我怎样才能以干净的方式实现这一目标?

2 个答案:

答案 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)来检查响应数据格式。缺点是当您的数据库发生变化时,您还需要更新变压器。