In the given code, when you access $author->books in the policy, it will not automatically load the books. It will result in a new query to the database to retrieve the books for each author.
To avoid the N+1 problem and improve performance, you can use eager loading in the policy as well. Here's an updated version of the code:
$authors = Author::with('books')->get();
...
foreach ($authors as $author) {
if (auth()->user()->can('view', $author)) {
foreach ($author->books as $book) {
...
}
}
}
...
// Policy
public function view(User $user, Author $author)
{
$author->load('books'); // Eager load the books
$books = $author->books;
...
}
By using $author->load('books'), you can eager load the books for each author in the policy, which will prevent additional queries to the database when accessing $author->books inside the loop.
This way, you can ensure that the books are already loaded and there won't be any extra queries to the database in the loop.