如何有条件地更改模型关系值

时间:2019-03-31 08:27:16

标签: laravel

我正在开发一个应用程序,其中存在不同类型的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类型。

在这一点上,我认为我的体系结构中存在一些我无法理解的缺陷,这就是为什么我寻求帮助。

如果您要到这里,非常感谢!

祝您有个美好的一天。

里卡多

1 个答案:

答案 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;
}