我正在开发一个应用程序,其中有不同类型的Order模型(每个Order类型都有他的相对模型)。我需要根据订单类型更改订单状态属性的名称,而不将其保存在数据库中(只是为了让最终用户更清楚)。 state属性是多对一关系(一个状态可以有不同的顺序),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类型。
在这一点上,我认为我的架构中存在一些我无法获得的缺陷,这就是我寻求帮助的原因。
如果你到这里,非常感谢!
祝大家一切顺利。
里卡多
我终于找到了你所面临的问题,并感谢你详细阐述了你的问题。
在Order
你有一个称为state
的雄辩的变异者同时有一个叫做state
的关系。当代码解析状态时,它将使用mutator
而不是预期的关系。重命名关系将有助于解决问题,而不是称之为ordertate。在这里,您可以看到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;
}