【问题标题】:How to generalize a resource function to be used in all controllers for different models?如何概括用于不同模型的所有控制器的资源函数?
【发布时间】:2020-01-28 20:25:12
【问题描述】:

在 laravel API 资源中:

我需要一种动态方法来概括所有控制器中要使用的所有资源的代码,而不是在每个控制器的所有方法中使用资源。为了更清楚,我有一个特征,包括返回 json 响应的通用函数数据和状态码,让我们来一个“示例函数”假设它是 showAll(Collection $collection) 用于返回指定模型的数据集合,例如它用于返回所有用户数据 .. 所以我需要构建一个函数来调用指定模型的任何资源,因为我知道我有很多模型......

a) 包含 showAll 方法的特征:

namespace App\Traits;

use Illuminate\Support\Collection;

trait ApiResponser
{
    private function successResponse($data, $code) {
        return response()->json($data, $code);
    }

    protected function showAll(Collection $collection, $code = 200) {

        $collection = $this->resourceData($collection);

        $collection = $this->filterData($collection);
        $collection = $this->sortData($collection);
        $collection = $this->paginate($collection);
        $collection = $this->cacheResponse($collection);
        return $this->successResponse([$collection, 'code' => $code], $code);
    }

    protected function resourceData(Collection $collection) {
        return $collection;
    }
}

b) 用户控制器作为示例

namespace App\Http\Controllers\User;

use App\User;
use Illuminate\Http\Request;
use App\Http\Controllers\ApiController;

class UserController extends ApiController
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = User::all();
        // Here the showAll(Collection $collection) is used
        return $this->showAll($users);
    }

}

c) 用户资源:


namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'identity' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'isVerified' => $this->verified,
            'isAdmin' => $this->admin,
            'createDate' => $this->created_at,
            'updateDate' => $this->updated_at,
            'deleteDate' => $this->deleted_at,
        ];
    }
}

generalize:表示在任何地方都使用,没有代码冗余

【问题讨论】:

    标签: php laravel api


    【解决方案1】:

    关于提供者,您可以在那里加载数据,并在可以访问用户数据的地方使该数据可访问?

    laravel docs

    【讨论】:

    • 谢谢你的回答,但我已经做了类似你所说的事情。我的问题是如何获取指定模型的资源。如果你知道分形变压器有一个属性与模型一起使用的称为转换器,它使我们能够获取模型实例的任何转换器......这是我的问题,所以我需要一种类似的方式来获取模型的资源
    【解决方案2】:

    我找到了一个简单的解决方案..通过添加以下方法

        protected function resourceData($collection) {
            $collection = get_class($collection[0]);
    
            $resource = 'App\Http\Resources\\' . str_replace('App\\', '', $collection) . 
            'Resource';
    
            return $resource;
         }
    
    1. 这个方法第一行的$collection[0]会得到 您当前使用的型号。
    2. get_class 将获得模型名称 ex: App\User
    3. 'App\Http\Resources\\' . str_replace('App\\', '', $collection): 这将通过在前面添加'App\Http\Resources\' 来获取资源的路径 型号
    4. str_replace('App\\', '', $collection): 将从集合中删除 App\ path 所以App\User 应该是User
    5. 然后'Resource' 将与之前的结果和整个 字符串应该是这样的:App\Http\Resources\UserResource
    6. 所以最后你应该返回整个字符串App\Http\Resources\UserResource ,最后你应该打电话给resourceData() showAll() 方法:
    protected function showAll(Collection $collection, $code = 200) {
        $collection = $this->resourceData($collection);
        $collection = $this->filterData($collection);
        $collection = $this->sortData($collection);
        $collection = $this->paginate($collection);
    
        //Calling resourceData() method
        $resource = $this->resourceData($collection);
    
        $collection = $this->cacheResponse($collection);
    
    
        return $this->successResponse([$resource::collection($collection), 'code' => $code], $code);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-06
      • 2020-12-09
      • 1970-01-01
      • 2020-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-15
      相关资源
      最近更新 更多