在子模型中使用多态关系会导致无限循环?

时间:2017-09-08 01:07:21

标签: php laravel laravel-5 eloquent polymorphism

这个问题已经被问到here但是没有得到答案。现在我面临同样的问题,但在laravel 5.4。我有一个模型Book,一个模型ReadingSession和一个模型Comment。一本书有许多阅读课程,并有很多评论,但阅读会议也可以有意见。所以我的关系定义如下:

book.php中

protected $with = [
    'author',
    'readingSessions',
    'userRating',
    'ratings',
    'comments'
];

public function users()
{
    return $this->belongsToMany(User::class, 'user_book');
}

public function author()
{
    return $this->belongsTo(Author::class);
}

public function allReadingSessions()
{
    return $this->hasMany(ReadingSession::class);
}

public function readingSessions()
{
    return $this->hasMany(ReadingSession::class)
                ->where('user_id', Auth::user()->id);
}

public function ratings()
{
    return $this->hasMany(Rating::class);
}

public function userRating()
{
    return $this->hasMany(Rating::class)
                ->where('user_id', Auth::user()->id);
}

public function comments()
{
    return $this->morphMany('App\Models\Comment', 'commentable');
}

ReadingSession.php

protected $with = ['comments'];

public function user()
{
    return $this->belongsTo(User::class);
}

public function book()
{
    return $this->belongsTo(Book::class);
}

public function comments()
{
    return $this->morphMany('App\Models\Comment', 'commentable');
}

Comment.php

public function commentable()
{
    return $this->morphTo();
}

这似乎创造了一个无限循环。有谁能暗示我做错了什么?

1 个答案:

答案 0 :(得分:3)

你可能有一个无限循环的主要原因是你试图自动加载一个关系,而这个关系又试图对之前的模型做同样的事情。

将它放在一个例子中:

book.php中

protected $with = [
    'author',
];

public function author()
{
    return $this->belongsTo(Author::class);
}

Author.php

protected $with = [
    'books',
];

public function books()
{
    return $this->hasMany(Book::class);
}

在这种情况下,每次你获取一个作者时,它都会自动获取他的书籍,而这些书籍又将试图获取作者......等等...

可能发生的另一件事情,更难以实现的是在某些访问器上使用$appends属性。如果您尝试通过$appends自动将变量放入模型中,并且如果该访问者以某种方式获取关系或使用关系,则可能会再次获得无限循环。

实施例: Author.php

protected $appends = [
    'AllBooks',
];

public function books()
{
    return $this->hasMany(Book::class);
}

public function getAllBooksAttribute() {
    return $this->books->something...
}

在这种情况下,每当应用尝试解析您的作者模型时,它都会获取图书,而这些图书又会获取作者,而这又会再次获取图书......

从你的片段中,不清楚是什么导致了这个问题,但是这个答案可能会给搜索它的地方提供一些线索。

要解决此问题,您可以从$with中移除关系并手动加载:$author->load('books')Author::with('books')->where... 您还可以通过这种方式加载关系关系,例如:$author->load('books', 'books.comments')Author::with('books', 'books.comments')->where...

这一切都归结为你想要实现的目标。因此,您必须评估应自动加载的内容和内容。

在自动加载模型上的关系以及向$appends添加访问者时要小心,特别是如果他们使用关系。这是一个很棒的功能,但有时候会很难吃。