Back

Order queries subsets of related fields


Mat posted 3 weeks 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 1 week 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 1 week 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