Search code examples
laravelrelationships

laravel through relation - I'm lost


I have this very basic problem. I have 3 models: Author - Book - Excerpt

In Author I have this relation:

public function autoredExcerpts()
{
    return $this->hasMany('App\Excerpt', 'author_id');
}

In my VIEW I want to display author info and list all excerpts from his books. I have this

@foreach ($author->autoredExcerpts as $xc)
<div class="box_excerpt">
{{$xc->content}}  //prints the excerpt
<span class="source">{{ $xc->book_id}}</span>  // now it prints the book's id only
</div>
@endforeach

How I can print the book's name?

In the Book model the column with name is simply 'title'

Important: There will be multiple excerpts from one book and in case of many authors - many books. I guess I need HasOneThrough relation.


Solution

  • You can use hasManyThrough to relate the Author to his Excerpts, and use a belongsTo to relate the Excerpt back to its Book:

    Has-many-through relationship between the Author and his Books:

    class Author extends Eloquent {
    
        public function excerpts()
        {
            return $this->hasManyThrough('Excerpt', 'Book');
        }
    

    Tell the Excerpt who he belongs to (assuming that each Excerpt can belong to only one Book):

    class Excerpt extends Eloquent {
    
        public function book()
        {
            return $this->belongsTo('Book');
        }
    

    Now in your view:

    @foreach ($author->excerpts as $excerpt)
      <div class="box_excerpt">
    
        {{ $excerpt->content }}  //prints the excerpt (assuming it's stored in 'content')
        <span class="source">{{ $excerpt->book->title }}</span>  // the book's name
    
      </div>
    @endforeach
    

    Just a final point on this: Eager Loading can makes it easy on your DB too.. I don't know where you are defining $author, but you can pull the records for the books and excerpts at the same time, to reduce calls to the DB:

    $author = Author::with('excerpts.book')->find($author_id);