按需附加访问者

时间:2014-11-07 10:48:00

标签: php laravel laravel-4 eloquent accessor

我正在尝试有时 Accessor 附加到 Eloquent 查询的结果中。

这是我的访问者:

public function getCatAttribute() {
    return "Here's a cat!";
}

如果我使用protected $appends = array('cat');数组附加它,它每次都会加载它。

然而,当删除它时,由于我不希望它总是附加它,我无法将其加载到 Eloquent 查询中。

这是我尝试的内容:

$items = Item::with('cat')->get();

我怎样才能做到这一点?

4 个答案:

答案 0 :(得分:1)

我不知道我是否理解了这个问题,但您可以为不存在的属性创建访问者。假设您有cat属性,您可以创建:

public function getModCatAttribute($value) {
  if ($this->cat == 'dog') {
     return "I'm a dog";
  }
  return $this->cat;
}

因此您现在可以访问$model->cat$model->mod_cat。对于一般用法,此方法更好,因为您将始终访问原始属性和已修改的属性,并且您始终知道哪个属性已被修改。

但你也可以这样做:

public function getCatAttribute($value) {
  if ($this->cat == 'dog') {
     return "I'm a dog";
  }
  return $this->cat;
}

现在您可以访问$model->cat,结果取决于$cat属性中的内容。

答案 1 :(得分:0)

编辑:

IMO唯一的方法是扩展模型类,并使用$appends。所以像

class ModelWithCat extends MyModel
{
    protected $appends = ['cat_attribute']
}

然后将其命名为

ModelWithCat::get();

以下是我的旧答案供您参考:

我正在整理类似的问题,就我而言,我需要将JSON数据从查询生成器输入到Vue表中,并且需要在后端转换数据,因此vue表可以直接使用数据。我在控制器中的代码如下:

$query = Photo::query()->with(['user']);
if($filter) {
    $query->where('title', 'like', "%{$filter}%")
}
return $query->orderBy($field, $dir)->paginate($limit)

我还没有找到触发集合访问器的方法,也无法遍历Paginator类的结果。最终,我意识到这最终将返回JSON,可以在发送到Vue之前对其进行修改。所以我以这样的结尾:

// transform the data before return them
$res_json = $query->orderBy($field, $dir)->paginate($limit)->toJson();
$res_decoded = json_decode( $res_json );
foreach($res_decoded->data as $item) {
    // transform the data.. you could probably call your accessor here like 
    // $item->cat = $item->cat , for me it was easier to just write the logic
    // here instead
    $item->license = 'dynamic-license';
}
return response()->json($res_decoded);

我知道它很丑陋,但这是我发现的唯一方法,而且我只在一个地方使用它,所以我认为我必须忍受这一点。也许可以帮助某人。

答案 2 :(得分:0)

对不起,我参加聚会迟到了。

你不能做:

$items = Item::with('cat')->get();

因为访问器是一个计算的属性,这意味着它需要首先具有模型实例的实际属性。

相反,您可以执行以下操作:

$items = Item::get();
$items->append('cat'); // this allows you to append accessors on-demand

答案 3 :(得分:0)

我知道这是一个较晚的发布,但是对于其他一些想了解想法的简单方法,可以在查询调用中使用append方法来实现最新版本的按需IMO。在上面的某些答案中已经存在。

Item::get()->append('attibute_name');

此外,在进行分页时

$paginate = Item::paginate(10); // receive LengthAwarePaginator Instance
$items = collect($paginate->items()); // receive paginated items only to append
$items->each->append('attribute_name') // then simply you append it what auto accessor will do in toArray()

您明白了。