繁体   English   中英

Laravel,如何忽略访问器

[英]Laravel, how to ignore an accessor

我有一个带有自定义访问器的模型,所以我得到了那个自定义属性,

    class Order extends GSModel{

        $appends = ['orderContents'];

        public function getOrderContentsAttribute()
        {
            return $this->contents()->get();
        } 
 }

但是现在,在一种情况下,我只需要获取一些字段,而不需要这个OrderContents之一。

$openOrders         = Order::open()->has('contents')->get(['id','date','tableName']);

但是这样做,它也会返回OrderContents给我。有没有办法不获取该字段?

谢谢!

令人失望的是这里的人给了你虚假的信息。 实际上有一个内置的方法可以实现这一点,直接写入Illuminate\Database\Eloquent\Model类,称为Model::getOriginal

要检索foo属性,忽略在Model::getFooAttribute中定义的访问器,只需调用$myModel->getOriginal('foo'); . 此方法在Illuminate\Database\Eloquent\Model的第3087行定义。

请记住,此方法获取模型的原始值。 这意味着,如果您对该模型实例的属性进行任何修改,上述解决方案将不会反映这些修改。 只要您只是检索值,就应该没有问题。

没有办法一口气完成,所以这就是你需要的:

$openOrders = Order::open()->has('contents')->get(['id','date','tableName']);

$openOrders->each(function ($order) {
  $order->setAppends([]);
});

或者,您可以在最后一步使用 Laravel 的高阶消息传递

$openOrders->each->setAppends([]);

好的,我并不是说这是一个很好的解决方案,但它可以工作,并且您可以使用循环来解决...

将此添加到您的模型中:

public static $withoutAppends = false;

protected function getArrayableAppends()
{
    if(self::$withoutAppends){
        return [];
    }
    return parent::getArrayableAppends();
}

然后当你想禁用$appends属性时:

Order::$withoutAppends = true;
$openOrders = Order::open()->has('contents')->get(['id','date','tableName']);

对于 Laravel <= 6.x,

有一个内置的getOriginal方法可以在没有访问器的情况下从模型中获取原始值。 见: 6.x

$myModel->getOriginal('foo');

对于 Laravel 7.x 和 8.x,

您应该使用getRawOriginal内置方法从模型中检索原始值。 见: 8.x

$myModel->getRawOriginal('foo');

7.x & 8.x 中的getOriginal方法将通过访问器返回属性值。

从模型类中获取未变异值的更一致和可靠的方法是从 attributes 属性中检索它,如下所示:

$this->attributes['name']

但请注意,属性是受保护的属性,因此您不能从模型类外部执行此操作。 在这种情况下,您可以使用

$model->getAttributes()['name']

在 Laravel 8 中为我工作

将此添加到您的模型中:

public function newInstance($attributes = [], $exists = false): self
{
    $model = parent::newInstance($attributes, $exists);
    $model->setAppends($this->appends);

    return $model;
}

public static function withoutAppends(): Builder
{
    $model = (new static);
    $model->setAppends([]);

    return $model->newQuery();
}

暂时禁用$appends

$openOrders = Order::withoutAppends()->open()->has('contents')->get(['id','date','tableName']);

如果您运行像$orders = Order::get();这样的辅助查询附件又回来了。

假设您在加载关系并且 contents() 是关系时只需要自定义属性值,您可以执行以下操作:

public function getOrderContentsAttribute()
{
  if ($this->relationLoaded('contents')) {
    return $this->contents()->get();
  } else {
    return [];
  }
}

然后,为了访问该属性,您可以在查询模型时使用查询范围添加关系或Order::with('contents')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM