雄辩的ORM对象关系

时间:2014-11-11 11:33:52

标签: php laravel eloquent illuminate-container

我有两张桌子。学校和学生。

当我取得所有学生时

Student::all()->toJson();

我收到回复

[
  {
    "id": 1,
    "school_id": 1,
    "name": "Jhon"
  }
]

但实际上我想收到

[
  {
    "id": 1,
    "school": {
        "id": 1
    },
    "name": "Jhon"
  }
]

我知道我能做到

Student::with(['school']);

但是它对学校表做了额外的查询,这是没有必要的,因为我只需要学校ID,而不是所有其他属性。

2 个答案:

答案 0 :(得分:1)

您可以覆盖模型中的toArray方法。使用toJson也可以实现同样的目的,但toArray会调用toJson,我认为toArray

更能做出更好的事情
class Student extends Eloquent {

    public function toArray($options = 0){
        $this->school = ['id' => $this->school_id];
        unset($this->school_id);

        return parent::toArray($options);
    }
}

修改

保持模型相同,只改变为输出(可能更好)

public function toArray($options = 0){
    $array = parent::toArray($options);
    $array['school'] = ['id' => $array['school_id']];
    unset($array['school_id']);
    return $array;
}

答案 1 :(得分:1)

您可以使用Illuminate\Support\Collection的{​​{1}}方法获得更自动化的解决方案:

transform

如果你打算多次调用它(我假设你会这样做),最好是扩展$students = Student::all(); $students->transform(function($el) { $el = $el->toArray(); foreach ($el as $k => $v) { if (substr($k, -3) === '_id') { $el[substr($k, 0, -3)]['id'] = $v; unset($el[$k]); } } return $el; }); return $students; 并添加一个方法来做到这一点。然后编辑基础模型上的Illuminate\Database\Eloquent\Collection方法以使用新的扩展类。