自定义访问者Eloquent Model

时间:2015-06-08 16:16:28

标签: arrays laravel model eloquent

我有一个Eloquent模型,我想创建一个自定义的toArray方法......

class Posts extends Model {

    public function scopeActives($query)
    {
        return $query->where('status', '=', '1');
    }

    public function toCustomJS()
    {
        $array = parent::ToArray();
        $array['location'] = someFunction($this->attributes->location);

        return $array;
    }
}

//In my controller:

Posts::actives()->get()->toArray(); //this is working
Posts::actives()->get()->toCustomJS(); //Call to undefined method Illuminate\Database\Eloquent\Collection::toCustomJS()

如何覆盖toArray方法或创建另一个“导出”方法?

1 个答案:

答案 0 :(得分:2)

get()实际上返回一个Collection对象,其中包含0,1或许多可以迭代的模型,因此难怪为什么将这些函数添加到模型中是行不通的。要使其工作,您需要做的是创建自定义Collection类,覆盖toArray()函数,并覆盖模型中负责构建该集合的函数,以便它可以返回自定义Collection对象。

CustomCollection类

class CustomCollection extends Illuminate\Database\Eloquent\Collection {

    protected $location;

    public function __construct(array $models = Array(), $location)
    {
        parent::__construct($models);
        $this->location = $location;
    }

    // Override the toArray method
    public function toArray($location = null)
    {
        $original_array = parent::toArray();

        if(!is_null($location)) {
            $original_array['location'] = someFunction($this->location);
        }

        return $original_array;
    }
}

覆盖模型上的newCollection方法

对于您希望返回的模型CustomCollection

class YourModel extends Eloquent {

    // Override the newCollection method
    public function newCollection(array $models = Array())
    {
        return new \CustomCollection($models, $this->attributes['location']);
    }

}

请注意,这可能不是您的意图。因为Collection实际上只是一个模型数组,所以依赖单个模型的location属性并不好。根据您的使用情况,它可以在不同型号之间发生变化。

将此方法放入特征中然后在您希望实现此功能的每个模型中使用该特征也可能是一个好主意。

修改

如果您不想创建自定义Collection课程,则每次都可以手动执行此操作...

$some_array = Posts::actives()->get()->toArray();
$some_array['location'] = someFunction(Posts::first()->location);
return Response::json($some_array);