Does using a polymorphic relation in a child model cause an infinite loop?

This question has already been asked here , but it has not received an answer. Now I am facing the same problem, but in laravel 5.4. I have a Book model, a ReadingSession model ReadingSession and a Comment model. The book has many reading sessions and many comments, but there may also be comments in the reading session. Therefore, my relationship is defined as follows:

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(); } 

They seem to create an endless loop. Can someone hint me what I'm doing wrong?

+5
source share
1 answer

The main reason you might have an infinite loop is because you are trying to automatically load relationships, which in turn are trying to do the same with the previous model.

Let's introduce it in an example:

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); } 

In this case, every time you pick up the author, he automatically downloads his books, which, in turn, will try to find the author and continue ...

Another thing that can happen, and it's harder to implement, is to use the $appends for some accessories. If you try to automatically have a variable in the model through $appends , and if this accessory gets a relation or uses some relation, you can get an infinite loop again.

Example: Author.php

 protected $appends = [ 'AllBooks', ]; public function books() { return $this->hasMany(Book::class); } public function getAllBooksAttribute() { return $this->books->something... } 

In this case, every time the application tries to resolve your Author model, it will retrieve books, which, in turn, will lead to the author, who, in turn, will download books again and again and more ...

It's not clear from your snippets what causes the problem, but this answer may give some clues where to look for it.

To solve this problem, you can remove the relation from $with and load it manually: $author->load('books') or Author::with('books')->where... You can also load the relation relation like this for example, $author->load('books', 'books.comments') or Author::with('books', 'books.comments')->where...

It all comes down to what you are trying to achieve. So, you should evaluate what and what you should not automatically download.

Be careful when automatically loading relationships on your models and when adding accessories to $appends , especially if they use relationships. This is an awesome feature, but can sometimes bite.

+3
source

Source: https://habr.com/ru/post/1271624/


All Articles