来自Laravel变压器类的模型调用

时间:2016-02-10 06:25:28

标签: laravel laravel-5

在将数据作为API调用的输出发送之前,我一直在使用变换器(分形)来转换数据。 所以从控制器我调用变换器类并传递像这样的数据

$data = $this
    ->myModelClass
    ->search($filters);

$data = $this
    ->listTransformer
    ->transform($data);

并在变压器中,

public function transform($result)
{
    $resource = $this->factory->make($result, function ($item) {

        return [
            'id'               => $item->id,
            'name'             => $item->name,
            'category_name'    => $this->anotherModel->getCategory($item->category_id),
            'revenue'          => $this->anotherModel->getRevenue($item->earnings)
        ];
    });

    $result = $this
        ->manager
        ->createData($resource)
        ->toArray();

    return $result['data'];
}

所以基本上,我从变压器调用模型。这是正确的做法吗?

我见过另一种使用包含的方法,但如果我在数组中有多个项目, 需要传递给模型以获取细节,我需要编写一些变换器。

1 个答案:

答案 0 :(得分:1)

一般来说,这是一种不好的做法,因为它违反了"单一责任" SOLID原理。您的变压器不再仅仅负责转换数据,现在它还会查询数据,然后将数据绑定到您的数据层,使其紧密耦合"。

将模型对象传递给包含其他相关模型的变换器是没有坏处的,但是变换器应该有一个责任,即转换数据。

通常我会为每个模型创建一个变换器,然后让域(聚合)模型使用其他显式变换器,这将涉及您构建一个"域" (聚合)模型之前将其传递给变压器。这意味着对数据层的任何更改都会对变换器产生最小的影响。

以下工作示例:

class LeadTransformer extends Transformer implements LeadTransformerInterface {

    /**
     * @var CustomerTransformerInterface
     */
    protected $customerTransformer;

    /**
     * @var EnquiryTypeTransformerInterface
     */
    protected $enquiryTypeTransformer;

    /**
     * @var PlanTransformerInterface
     */
    protected $planTransformer;

    /**
     * @param CustomerTransformerInterface $customerTransformer
     * @param EnquiryTypeTransformerInterface $enquiryTypeTransformer
     * @param PlanTransformerInterface $planTransformer
     */
    public function __construct(CustomerTransformerInterface $customerTransformer, EnquiryTypeTransformerInterface $enquiryTypeTransformer, PlanTransformerInterface $planTransformer)
    {
        $this->customerTransformer = $customerTransformer;
        $this->enquiryTypeTransformer = $enquiryTypeTransformer;
        $this->planTransformer = $planTransformer;
    }

    /**
     * Transforms a lead
     *
     * @param array $lead
     * @return array
     */
    public function transform($lead)
    {
        $data = [
            // Do Transformation
        ];

        if($lead->enquiry_type)
        {
            $data['enquiry_type'] = $this->enquiryTypeTransformer->transform($lead->enquiry_type);
        }

        if($lead->customer)
        {
            $data['customer'] = $this->customerTransformer->transform($lead->customer);
        }

        if($lead->plan)
        {
            $data['plan'] = $this->planTransformer->transform($lead->plan);
        }

        return $data;
    }
}

在上面的例子中,LeadTransformer有三个其他变换器被laravel的IoC Container注入为依赖。在转换相关模型中的数据时,使用了模型转换器。

这意味着我是否需要操纵"客户"模型,我没有必要干涉我的应用程序的其他方面,因为它都被抽象出来。

希望这能回答您的问题,如果您有任何后续问题请发表评论,我会尽力解决这些问题