重写后的标题为:What causes a "possible infinite loop" when accessing another model attribute in an appended attribute of a model?
P粉786432579
2023-09-04 17:47:10
<p>我的 <strong>Laravel 9</strong> 应用程序有两个模型: <code>brand</code> 模型和 <code>product</code> 模型。每个 <code>product</code> 属于一个 <code>brand</code>,而一个 <code>brand</code> 又属于多个 <code>products</code>(1:n 关系)。 <code>product</code> 模型应提供一个名为 <code>title_medium</code> 的“计算”(附加)属性,该属性根据请求连接品牌标题和产品标题。</p>
<p>一旦我尝试在产品模型的 <code>getTitleMediumAttribute()</code> 方法中访问 <code>$this->brand</code> , <code>xdebug</code> 就会抛出 <code>possibleInfiniteloop</code> 异常并取消执行(N次迭代后) 。我认为这与关系和加载序列(渴望加载)有关,但到目前为止我找不到解决方案。</p>
<h2>品牌模型</h2>
<p><code>brand</code> 模型有一个属性 <code>title</code> 并且有许多属于 <code>brand</code> 的 <code>products</code>。</p>
<pre class="brush:php;toolbar:false;">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);
}
}</pre>
<h2>产品型号</h2>
<p>每个<code>产品</code>都属于一个<code>品牌</code>。附加属性 <code>title_medium</code> 应连接品牌标题和产品标题。</p>
<pre class="brush:php;toolbar:false;">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;
}
}</pre></p>
尝试使用 属性 而不是 getTitleMediumAttribute,像这样并告诉我是否仍然遇到相同的错误(使用此方法而不是 `getTitleMediumAttribute):
属性
是\Illuminate\Database\Eloquent\Casts\Attribute