在Laravel 9中,更改字段并执行查找操作。

huangapple go评论54阅读模式
英文:

Mutating a field and performing a lookup in Laravel 9

问题

我有两个模型,CartIncodeCart 有一个名为 incode_txt 的字段,该字段被填充为一个包含字母和数字的字符串,例如 5td

当发生这种情况时,我有一个修改器来确保将字符串转换为大写,如下所示:

return Attribute::make(
    set: fn (string $value) => strtoupper($value)
);

这是根据 Laravel 文档 中定义修改器的方式完成的。到目前为止一切顺利。

然而,Cart 模型还有另一个名为 address_incode_id 的字段。每当设置 incode_txt 时,我想使用相同的 $valueIncode 模型上执行搜索,如下所示:

$incode = Incode::where('name', '=', $value)
    ->orWhere('name', 'LIKE', $value[0] . '%')
    ->first();

然后,我希望将 $incode->id 保存到 Cart 模型的 address_incode_id 字段上。

我的问题是:我是否可以以某种方式将这两个操作合并到同一个修改器中,如果可以,这是否是一个好主意?我想知道如何正确实现这样的操作方式。Laravel 文档中有一节关于 修改多个属性,但似乎与我的用例不相关。

英文:

I have two models, Cart and Incode. Cart has a field called incode_txt which gets populated with an alphanumeric string such as 5td

When this happens, I have a mutator to make sure the string gets converted to uppercase as so:

        return Attribute::make(
            set: fn (string $value) => strtoupper($value)
        );

This is done following the Laravel Docs for defining mutators. So far so good.

However, I also have another field on the Cart model called address_incode_id. Every time incode_txt is set, I want to perform a search on the Incode model using the same $value like this:

$incode = Incode::where('name', '=', $value)
    ->orWhere('name', 'LIKE', $value[0] . '%')
    ->first();

I then want $incode->id to be saved to the address_incode_id field on the Cart model.

My question: Can I somehow merge these two actions into the same mutator and, if so, is it even a good idea to do so? I'd like to know what the correct way to achieve something like this is. The Laravel docs has a piece about Mutating Multiple Attributes but it doesn't seem relevant to my use case.

答案1

得分: 1

以下是使用观察者的完整示例:

生成一个观察者

php artisan make:observer CartObserver --model=Cart

编辑生成的文件位于 app/Observers/CartObserver.php

以下是一个示例,仅观察更新事件,并检查特定属性是否已使用 isDirty 修改。

use App\Models\Cart;
use App\Models\Incode;

class CartObserver {

    public $afterCommit = true; // 在提交后触发

    public function updated(Cart $cart) {

        if ( $cart->isDirty('incode_txt') ) {
            
            $incode = Incode::where('name', $cart->incode_txt)
                ->orWhere('name', 'LIKE', $cart->incode_txt . '%')->first();

            if ( $incode ) {
                $cart->address_incode_id =  $incode->id;
                $cart->saveQuietly();

                // 否则,创建一个静默更新 Card 模型的作业

            }      
        }
    }
}

完成后,不要忘记在 app/Providers/AppServiceProvider.phpboot 方法中添加你的观察者:

use App\Models\Cart;
use App\Observers\CartObserver;

 `boot` 方法中:

Cart::observe(CartObserver::class);
英文:

Here's a full exmaple using Observers

Generate an Observer

php artisan make:observer CartObserver --model=Cart

edit the generated file in app/Observers/CartObserver.php

an example below that only observe updated event, the check if the specific attribute is modified using isDirty

use App\Models\Cart;
use App\Models\Incode;

class CartObserver  {

public $afterCommit = true; //trigger after commit

public function updated(Cart $cart) {

    if ( $cart->isDirty('incode_txt') ) {
        
        $incode = Incode::where('name', $cart->incode_txt)
            ->orWhere('name', 'LIKE', $cart->incode_txt . '%')->first();


        if ( $incode ) {

            /* $cart->fill([
                'address_incode_id' => $incode->id;
            ]); */

            $cart->address_incode_id =  $incode->id;
            $cart->saveQuietly();

            // Otherwise create a job that update the Card model quietly

        }
            

    }

}

}

After that, don't forget to add your observer in app/Providers/AppServiceProvider.php boot method

use App\Models\Cart;
use App\Observers\CartObserver;

and on boot

Cart::observe(CartObserver::class);

huangapple
  • 本文由 发表于 2023年6月15日 18:31:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/76481621.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定