求助 dingoApi + league/fractal 中,调用 transformer 中的另一个方法

// Transformers
class AssessTransformer extends TransformerAbstract
{
    /**
     * @param Assess $assess
     * @return array
     */
    public function transform(Assess $assess)
    {
        return [
            'id'            => $assess->assess_id,
            'doctor_id'     => $assess->doctor_id,
            'member_id'     => $assess->member_id,
            'parent_id'     => $assess->parent_id,
            'contents'      => $assess->body,
            'created_at'    => $assess->created_at,
        ];
    }

    /**
     * @param Assess $assess
     * @return mixed
     */
    public function contents(Assess $assess)
    {
        return $assess->contents;
    }
}

// 控制器中的回调
return $this->response->item($assess, (new AssessTransformer)->contents($assess));

// 现在的情况是:「AssessTransformer」的`transform`是其它控制器调用的,
// 但是目前的控制器也需要调用「AssessTransformer」,`transform`已经不适用于当前的`transform`方法.
// 那么,如何在当前的控制器中调用「AssessTransformer」的`contents`方法呢?
// 不会一个Transformers就执行一个`function`吧....
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

我经常使用的一种思路:

class AssessTransformer extends TransformerAbstract
{
    protected $type;

    public function __construct($type = '')
    {
        $this->type = $type;
    }

    /**
     * @param Assess $assess
     * @return array
     */
    public function transform(Assess $assess)
    {
        switch ($this->type) {
            default:
                return [
                    'id'            => $assess->assess_id,
                    'doctor_id'     => $assess->doctor_id,
                    'member_id'     => $assess->member_id,
                    'parent_id'     => $assess->parent_id,
                    'contents'      => $assess->body,
                    'created_at'    => $assess->created_at,
                ];
            case 'contents':
                return $assess->contents;
        }
    }
}

// 控制器中的回调
return $this->response->item($assess, new AssessTransformer('contents'));

而当返回值差异过大时,我也会实现两个 Transformer,类名上作区分即可

4年前 评论
讨论数量: 9

这么久了还无人解答,我先说一下 「LearnKu」上的一种解决方式(实际上并没有解决需求问题),代码如下:

 // 控制器中调用
return $this->response->item($assess, (new AssessTransformer)->detail($assess));

// Transformer 中
use League\Fractal\TransformerAbstract;
use App\Models\Assess;

class AssessTransformer extends TransformerAbstract
{
    public function transform(Assess $assess)
    {
        return [
            'id'            => $assess->assess_id,
            'doctor_id'     => $assess->doctor_id,
            'member_id'     => $assess->member_id,
            'parent_id'     => $assess->parent_id,
            'contents'      => $assess->body,
            'created_at'    => $assess->created_at,
        ];
    }

    public function detail($item)
    {
        return [
            'assess_id'     => $item->first()->assess_id,
            'parent_id'     => $item->first()->parent_id,
            'doctor_name'   => $item->first()->assess_id,
            'member_name'   => $item->first()->assess_id,
            'body'          => $item->first()->body,
            'created_at'    => $item->first()->created_at,
        ];
    }
}

然并卵,这种方式,依然在调用默认的 transform 方法。

4年前 评论

你是要在这个transformer 里边拼接数据吗?

4年前 评论

@daqiaowijiu 我是要调用 detail 方法。但他总是调用默认的 transform 方法

4年前 评论

再写一个transformer 呗,他继承的是抽象方法

4年前 评论

我经常使用的一种思路:

class AssessTransformer extends TransformerAbstract
{
    protected $type;

    public function __construct($type = '')
    {
        $this->type = $type;
    }

    /**
     * @param Assess $assess
     * @return array
     */
    public function transform(Assess $assess)
    {
        switch ($this->type) {
            default:
                return [
                    'id'            => $assess->assess_id,
                    'doctor_id'     => $assess->doctor_id,
                    'member_id'     => $assess->member_id,
                    'parent_id'     => $assess->parent_id,
                    'contents'      => $assess->body,
                    'created_at'    => $assess->created_at,
                ];
            case 'contents':
                return $assess->contents;
        }
    }
}

// 控制器中的回调
return $this->response->item($assess, new AssessTransformer('contents'));

而当返回值差异过大时,我也会实现两个 Transformer,类名上作区分即可

4年前 评论

@xinhuo 您的这种方式的确可以解决我现在所遇到的情况,可以解决燃眉之急。但是,这种方法还能再简洁一些吗?感觉这个依然有点不符合 laravel 的思想。

4年前 评论

@Savory 有很多这种情况的话,可以封装一个 Trait ,例如:

trait ComplexTransform
{
    protected $method;

    public function __construct($type = 'base')
    {
        $this->method = $type . 'Transform';
        if (!method_exists($this, $this->method)) {
            throw new \InvalidArgumentException("Non-existent transform method [{$this->method}]");
        }
    }

    public function transform($model)
    {
        return call_user_func([$this, $this->method], $model);
    }

    public static function __callStatic($name, $arguments)
    {
        return new static($name);
    }
}

在 AssessTransformer 中使用示例:

/**
 * @method static AssessTransformer base()
 * @method static AssessTransformer contents()
 */
class AssessTransformer extends TransformerAbstract
{
    use ComplexTransform;

    public function baseTransform(Assess $assess)
    {
        return [
            'id'            => $assess->assess_id,
            'doctor_id'     => $assess->doctor_id,
            'member_id'     => $assess->member_id,
            'parent_id'     => $assess->parent_id,
            'contents'      => $assess->body,
            'created_at'    => $assess->created_at,
        ];
    }

    public function contentsTransform(Assess $assess)
    {
        return $assess->contents;
    }
}

调用示例:

return $this->response->item($assess, AssessTransformer::contents());
//或
return $this->response->item($assess, new AssessTransformer('contents'));
4年前 评论

@xinhuo trait 好像没管用呢,还是在调用默认的 transform 方法。

4年前 评论
xinhuo 4年前

@xinhuo 大佬这种方法逻辑上是可行的。不过,这个 trait 类会和 dinggo 类的一些其他方法有冲突,比如我现在用的分页类就不能用这个方法了。我是第一次用这个 dinggo,等做完这个项目,一定要好好阅读一下 dinggo 的源码,合理解决一下这种实际情况。

file

4年前 评论
xinhuo 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!