首页 > 解决方案 > 如何在 Eloquent 中隐藏关系列?

问题描述

我有连接三个表的 Eloquent 查询。

      $result = Kompaniya::with(['Otdel'=>function($query){
            $query->select('kompaniya_id','title as otdel','id');
            $query->with(array('polzovatel'=>function($query){
                    $query->select('otdel_id',DB::raw("CONCAT(fam, ' ', imya, ' ', otchestvo) AS full_name"));
                }));
        }])
            ->get(['title as kompaniya','id']);

因为我使用 WITH 函数,所以必须选择 ID。但结果它是不必要的。它看起来像一棵树。那么如何隐藏不必要的字段呢?结果视图:

{
    "data": [
        {
            "kompaniya": "Pfeffer-White",
            "otdel": [
                {
                    "kompaniya_id": 1,
                    "otdel": "Securities Sales Agent",
                    "id": 7,

但结果应该是:

 "data": [
        {
            "kompaniya": "Pfeffer-White",
            "otdel": [
                {
                    "otdel": "Securities Sales Agent",

没有 kompaniya_id 和 id

那么我如何隐藏这些字段,而模型中没有 $hidden,可能正在使用 makeHidden?

标签: jsonlaraveleloquent

解决方案


就您而言,由于您要返回 JSON 响应,因此我认为最好的解决方案是使用API Resources

在构建 API 时,您可能需要一个位于 Eloquent 模型和实际返回给应用程序用户的 JSON 响应之间的转换层。Laravel 的资源类允许你将你的模型和模型集合转换成 JSON。

通过这种方式,您可以根据需要创建不同类型的响应。这是一个例子:

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {

        // Since the $request object is passed as input, you can check
        // parameters, route names, and so on. This example uses the route name

        $default = [
          'name' => $this->name,
          'email' => $this->email
        ];

        if($request->routeIs('profile')) {
          $default['profile'] = new ProfileResource($this->whenLoaded('profile'));
        } else if($request->routeIs('orders')) {
          $default['accountNumber'] = $this->account_number;
          $default['orders'] = new OrdersCollection($this->whenLoaded('orders'));
          $default['invoices'] = new InvoicesCollection($this->whenLoaded('invoices'));
        }

        return $default;
    }
}

通过这种方式,您可以根据请求和显示/隐藏字段在单个资源模型中拥有多个请求和 json 响应,而无需更改模型默认行为。

另一种方法可能是为每个请求创建一个资源,但在我看来,这将违反DRY 原则


推荐阅读