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']);
但是这样做,returns 我也是 OrderContents
..
有没有办法不获取该字段?
谢谢!
没办法一下子搞定,所以你需要的是:
$openOrders = Order::open()->has('contents')->get(['id','date','tableName']);
$openOrders->each(function ($order) {
$order->setAppends([]);
});
或者,您可以在最后一步使用 Laravel 的 Higher Order Messaging:
$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']);
令人失望的是这里的人给了你虚假信息。实际上有一个内置方法可以实现这一点,直接写入 Illuminate\Database\Eloquent\Model
class,称为 Model::getOriginal
.
要检索 foo
属性,忽略其在 Model::getFooAttribute
中定义的访问器,只需调用 $myModel->getOriginal('foo');
。此方法在 Illuminate\Database\Eloquent\Model
的第 3087 行定义。
请记住,此方法获取模型的 原始 值。这意味着如果您对该模型实例的属性进行任何修改,上述解决方案将不会反映这些修改。只要你只是检索值,你应该没有问题。
从模型 class 中获取未突变值的更一致和可靠的方法是从属性 属性 中检索它,如下所示:
$this->attributes['name']
但请注意,属性是受保护的 属性,因此您不能从模型外部执行此操作 class。在这种情况下,您可以使用
$model->getAttributes()['name']
我在 Laravel 8
工作
对于 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
方法将通过访问器 return 属性值。
将此添加到您的模型中:
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')
当您查询模型时。
我有一个带有自定义访问器的模型,所以我得到了那个自定义属性,
class Order extends GSModel{
$appends = ['orderContents'];
public function getOrderContentsAttribute()
{
return $this->contents()->get();
}
}
但是现在,在一种情况下,我只需要获取一些字段,而没有这个 OrderContents
。
$openOrders = Order::open()->has('contents')->get(['id','date','tableName']);
但是这样做,returns 我也是 OrderContents
..
有没有办法不获取该字段?
谢谢!
没办法一下子搞定,所以你需要的是:
$openOrders = Order::open()->has('contents')->get(['id','date','tableName']);
$openOrders->each(function ($order) {
$order->setAppends([]);
});
或者,您可以在最后一步使用 Laravel 的 Higher Order Messaging:
$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']);
令人失望的是这里的人给了你虚假信息。实际上有一个内置方法可以实现这一点,直接写入 Illuminate\Database\Eloquent\Model
class,称为 Model::getOriginal
.
要检索 foo
属性,忽略其在 Model::getFooAttribute
中定义的访问器,只需调用 $myModel->getOriginal('foo');
。此方法在 Illuminate\Database\Eloquent\Model
的第 3087 行定义。
请记住,此方法获取模型的 原始 值。这意味着如果您对该模型实例的属性进行任何修改,上述解决方案将不会反映这些修改。只要你只是检索值,你应该没有问题。
从模型 class 中获取未突变值的更一致和可靠的方法是从属性 属性 中检索它,如下所示:
$this->attributes['name']
但请注意,属性是受保护的 属性,因此您不能从模型外部执行此操作 class。在这种情况下,您可以使用
$model->getAttributes()['name']
我在 Laravel 8
工作对于 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
方法将通过访问器 return 属性值。
将此添加到您的模型中:
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')
当您查询模型时。