重写后的标题为:What causes a "possible infinite loop" when accessing another model attribute in an appended attribute of a model?
P粉786432579
P粉786432579 2023-09-04 17:47:10
[PHP讨论组]

我的 Laravel 9 应用程序有两个模型: brand 模型和 product 模型。每个 product 属于一个 brand,而一个 brand 又属于多个 products(1:n 关系)。 product 模型应提供一个名为 title_medium 的“计算”(附加)属性,该属性根据请求连接品牌标题和产品标题。

一旦我尝试在产品模型的 getTitleMediumAttribute() 方法中访问 $this->brandxdebug 就会抛出 possibleInfiniteloop 异常并取消执行(N次迭代后) 。我认为这与关系和加载序列(渴望加载)有关,但到目前为止我找不到解决方案。

品牌模型

brand 模型有一个属性 title 并且有许多属于 brandproducts

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Str;

class Brand extends Model
{
    use HasFactory;

    /**
     * Additional attributes for this model
     */
    protected $appends = [
        'prices'
    ];

    protected $fillable = [
        'title'
    ];

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::creating(function ($brand) {
            $brand->slug = Str::slug($brand->title, '-', 'de');
        });
    }

    /**
     * Returns all products for a brand
     *
     * @return HasMany
     */
    public function products(): HasMany
    {
        return $this->hasMany(Product::class);
    }
}

产品型号

每个产品都属于一个品牌。附加属性 title_medium 应连接品牌标题和产品标题。

namespace App\Models;

class Product extends Model
{
    use HasFactory, Searchable, Filterable;

    protected $fillable = [
        'title',
        'brand_id',
        'image'
    ];

    /**
     * Additional attributes for this model
     */
    protected $appends = [
        'title_long',
        'lowest_price',
        'highest_discount_percent_price',
        'latest_price_date',
        'price_count'
    ];

    /**
     * The "booted" method of the model.
     *
     * @return void
     */
    protected static function booted()
    {
        static::creating(function ($product) {
            $product->slug = Str::slug($product->title_long, '-', 'de');
        });
    }

    /**
     * Product belongs to one brand
     */
    public function brand(): BelongsTo
    {
        return $this->belongsTo(Brand::class);
    }

    /**
     * Get the combined title from product and brand
     */
    public function getTitleMediumAttribute(): string
    {
        // THIS CAUSES A "POSSIBLE INFINITE LOOP EXCEPTION" in xdebug
        return $this->brand->title . ' ' . $this->title;
    }
}

P粉786432579
P粉786432579

全部回复(1)
P粉306523969

尝试使用 属性 而不是 getTitleMediumAttribute,像这样并告诉我是否仍然遇到相同的错误(使用此方法而不是 `getTitleMediumAttribute):

public function titleMedium(): Attribute
{
    return Attribute::get(
        fn () => "{$this->brand->title} $this->title",
    );
}

属性\Illuminate\Database\Eloquent\Casts\Attribute

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号