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

Ant*_*ado 5 php polymorphism laravel eloquent laravel-5

这个问题已在这里提出,但没有得到答复.现在我面临同样的问题,但在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');
}
Run Code Online (Sandbox Code Playgroud)

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');
}
Run Code Online (Sandbox Code Playgroud)

Comment.php

public function commentable()
{
    return $this->morphTo();
}
Run Code Online (Sandbox Code Playgroud)

这似乎创造了一个无限循环.任何人都可以暗示我做错了吗?

fli*_*jms 3

可能出现无限循环的主要原因是,如果您尝试自动加载一个关系,而该关系又尝试对先前的模型执行相同的操作。

将其放入示例中:

图书.php

protected $with = [
    'author',
];

public function author()
{
    return $this->belongsTo(Author::class);
}
Run Code Online (Sandbox Code Playgroud)

作者.php

protected $with = [
    'books',
];

public function books()
{
    return $this->hasMany(Book::class);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,每次您获取作者时,它都会自动获取他的书籍,而书籍又会尝试获取作者,等等......

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

示例:Author.php

protected $appends = [
    'AllBooks',
];

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

public function getAllBooksAttribute() {
    return $this->books->something...
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,每次应用程序尝试解析您的作者模型时,它都会获取书籍,进而获取作者,进而再次获取书籍......

从您的代码片段来看,尚不清楚导致问题的原因,但此答案可能会提供一些线索来搜索它。

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

这一切都取决于您想要实现的目标。因此,您必须评估应该自动加载什么和不应该自动加载什么。

在模型上自动加载关系以及向 中添加访问器时要小心$appends,特别是当它们使用关系时。这是一个很棒的功能,但有时会很困难。