Back

Order queries subsets of related fields


Mat posted 11 months ago

Let's say that I have two models: Authors and Books

class Authors extends Model
{
    public function books() {
        return $this->hasMany('App\Books', 'id_author', 'id');
    }
}

class Books extends Model
{
    public function author() {
        return $this->belongsTo('App\Authors', 'id_author', 'id');
    }
}

In my controller I get the author collection:

$authors = Authors::orderBy('surname');

Then, in my view I want to display the authors in alphabetical order, and then each author's books.

@foreach ($authors as $author)
	{{ $author->surname }}<br>
	@foreach ($author->books as $book)
		{{ $book->title }}<br>
	@endforeach
@endforeach

What if I want to list all books subset using a specific order? For example, alphabetically by title or by publishing date? I'm almost sure there's simple and straight way to do this!

Firtzberg replied 11 months ago

Hi Mat,

Yeah there is. You can order the books when retrieving them from the DB or order the Laravel collection after it is retrieved. I recommend you to order them when retrieving them from the database. To do so use orderBy.

@foreach ($author->books()->orderBy('title')->get() as $book)

Note that

$author->books;

is the same as

$author->books()->get();

when invoked the first time. The explicit get will query the database every time, while the magic property stores the value of the books and makes a single query if used multiple times.

I think you can make the books ordered by default by adding the orderBy in the books() method.

return $this->hasMany('App\Books', 'id_author', 'id')->orderBy('title');
Firtzberg replied 11 months ago

Also make sure that when you get the authors from the database you get them together with the books.

$authors = Author::with('books')-...>get();

to avoid numerous queries.


Sign in to participate in this thread!



We'd like to thank these amazing companies for supporting us