我正在开发一个应用程序,其中存在不同类型的Order模型(每种Order类型都有其相对模型)。 我需要根据订单的类型更改订单状态属性的名称,而不将其保存在数据库中(只是为了让最终用户更清楚)。 状态属性是多对一关系(一个状态可以具有不同的顺序),而OrderState模型具有一个ID和一个名称。
结构如下
Order
- title
- (Some other meta data)
- state_id
OrderState
- id
- name
订单上的belongsTo关系使用Order.state_id和Order.id
我想要做的是,当我获得order-> state-> name时,我希望它检查某些条件(在这种情况下为州的ID),如果订单属于特定类型,返回一个不同的名称,而不是默认名称。
在每个订单模型中,状态声明如下:
public function state() {
return $this->belongsTo('App\OrderState', 'state_id', 'id');
}
这是我在调用order-> state时要应用的逻辑
在InstantOrder模型上:
...
public function getStateAttribute() {
if($this->state->id === 1) {
$this->state->name = 'Foo';
}
return $this->state->name;
}
...
在ClassicOrderModel上:
...
public function getStateAttribute() {
if($this->state->id === 1) {
$this->state->name = 'Bar';
}
return $this->state;
}
...
但这似乎不起作用,因为出现此错误
ErrorException: Undefined property: App\ClassicOrder::$state
/Applications/MAMP/htdocs/application/app/ClassicOrder.php:338
/Applications/MAMP/htdocs/application/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:446
/Applications/MAMP/htdocs/application/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:346
/Applications/MAMP/htdocs/application/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php:319
/Applications/MAMP/htdocs/application/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:1519
我当时正在考虑将此逻辑放在观察者上,当触发检索到的事件时,他将应用先前解释的那些更改;但这对我来说不合适。
我正在考虑的另一种方法是将此逻辑放在模型上。这种方式仍然感觉不正确,我也看不到这样做的方法。
我最后想到的方法是将此逻辑放在OrderState模型上,但我不知道如何获取Order类型。
在这一点上,我认为我的体系结构中存在一些我无法理解的缺陷,这就是为什么我寻求帮助。
如果您要到这里,非常感谢!
祝您有个美好的一天。
里卡多
答案 0 :(得分:1)
我终于找到了您面临的问题,并感谢您提出问题。
在Order
上,您有一个雄辩的mutator,名为state
,同时有一个名为state
的关系。当代码解析状态时,它将使用mutator
而不是预期的关系。重命名关系将有助于解决该问题,请改名为orderstate。在这里,您可以看到Laravel代码在哪里进行检查GetAttribute
如何执行此操作的代码示例。
public function OrderState() {
return $this->belongsTo('App\OrderState', 'state_id', 'id');
}
public function getStateAttribute() {
$state = $this->OrderState;
if($this->OrderState->id === 1) {
$state->name = 'Bar';
}
return $state;
}