【问题标题】:Laravel, Reusable API Resource methodLaravel,可重用 API 资源方法
【发布时间】:2018-03-11 08:55:22
【问题描述】:

所以我创建了一个 API 资源,并在 toArray() 方法中过滤了哪些属性通过查询字符串返回。我希望能够对我的大部分 API 资源执行此操作,因此将其移入可重用方法是有意义的。最好的方法是什么?

我正在考虑扩展基础Resource,但我不确定我将如何去做。还是应该将其移动到服务类或存储库中?

我的方法如下;

public function toArray($request)
{
    if($request->fields) {
        $fields         = [];
        $selectedFields = explode(',', $request->fields);
        foreach($selectedFields as $field) {
            if(isset($this->{$field})) {
                $fields[$field] = $this->{$field};
            }
        }
        return $fields;
    } else {
        return parent::toArray($request);
    }
}

理想情况下,我想做类似...

public function toArray($request)
{
    if($request->fields) {
        return parent::filterFields($request); // Not sure whether it should be parent::, $this or something else?
    } else {
        return parent::toArray($request); // Not sure whether it should be parent::, $this or something else?
    }

    // or event just
    return parent::filterFields($request); // Not sure whether it should be parent::, $this or something else?
}

全班:

ProjectResource.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ProjectResource extends Resource
{

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        dd(parent::filterFields());
        // or
        dd($this->filterFields());

        if($request->fields) {
            $fields         = [];
            $selectedFields = explode(',', $request->fields);
            foreach($selectedFields as $field) {
                if(isset($this->{$field})) {
                    $fields[$field] = $this->{$field};
                }
            }
            return $fields;
        } else {
            return parent::toArray($request);
        }
    }
}

Test.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class Test extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function filterFields($request)
    {
        return 'test';
    }
}

谢谢!

【问题讨论】:

    标签: laravel api resources extend


    【解决方案1】:

    你可以扩展资源

      <?php
            
            namespace App\Http\Resources;
            
            use App\Http\Resources\Product as ProductResource;
            
            class ProductQuantity extends ProductResource
            {
                /**
                 * Transform the resource into an array.
                 *
                 * @param  \Illuminate\Http\Request  $request
                 * @return array
                 */
                public function toArray($request)
                {
                    $parent = parent::toArray($request);
            
                    return array_merge($parent, [
                        'depotsQuantity' => $this->warehouses->sum('pivot.quantity'),
                    ]);
                }
            }
    

    【讨论】:

      【解决方案2】:

      如果要扩展类,可以使用parent::$this-&gt;。区别在于parent 将始终引用父类,$this 仅在当前类上不存在该方法时才会引用父类。因此,使用$this 允许扩展方法和属性。

      例子:

      <?php
      class A {
          public function test() {
              echo 'A';
          }
      }
      
      class B extends A {
          public function test() {
              echo 'B';
          }
      
          public function callParent(){
              parent::test();
          }
      
          public function callThis() {
              $this->test();
          }
      }
      
      
      $b = new B();
      $b->callParent(); // Echoes A
      $b->callThis(); // Echos B
      

      在您更新的类表示中,您有两个类都扩展了 Resource,但 ProjectResource 将不知道 Test 中的方法。您将需要 ProjectResource 来扩展 Test,它还将从 Resource 继承方法,因为 Test 扩展了 Resource(多重继承)。


      除此之外,您的实施方式将基于意见,并且您有很多选择。你可以扩展一个抽象类,你可以使用一个专门的过滤类,或者你可以使用一个 trait。

      【讨论】:

      • 我都试过了,但都没有成功,get_parent_class 返回资源类,但是当我尝试parent::filterFields()$this-&gt;filterFields() 时,我得到Call to undefined method App\Project::filterFields(),所以看起来它指的是不同的类?
      • 你能发布你的完整课程吗?
      • 另外,澄清一下,我想扩展 Resource 类,以便 filterFields 可用于它的所有实例。
      • ProjectResource 必须扩展 Test,而不是 Resource。
      • 这很有道理,不知道为什么我之前没有意识到这一点!干杯
      猜你喜欢
      • 1970-01-01
      • 2020-06-13
      • 2020-03-23
      • 1970-01-01
      • 2019-01-10
      • 2013-12-08
      • 2018-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多