Laravel WhereHas and With:

Quick recall

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;class Book extends Model
{
/**
* Get the author that wrote the book.
*/
public function author()
{
return $this->belongsTo(Author::class);
}
}
$books = Book::with(‘author’)->get();
foreach ($books as $book) {
echo $book->author->name;
}
select * from books
select * from authors where id in (1, 2, 3, 4, 5, …)

$authors = Author::whereHas(‘books’, function (Builder $query) {
$query->where(‘title’, ‘like’, ‘PHP%’);
})->get();
Select * from authors WHERE EXISTS(SELECT * FROM authors WHERE authors.id = books.author_id and books.title like ‘PHP%’);
foreach ($authors as $author) {
echo $author->book->title;
}
$authors = Author::with(‘books’)
->whereHas(‘books’, function (Builder $query) {
$query->where(‘title’, ‘like’, ‘PHP%’);
})
->get();
select * from authors WHERE EXISTS(SELECT * FROM authors WHERE authors.id = books.author_id and books.title like ‘PHP%’);select * from books where `books`.`author_id` in (1, 5, 11, 22, 46, 62, ….)
[
App\Author : {
id: 1
name: “author 1”,
…,
books: [
App\Books: {
….
title: ‘PHP’
},
App\Books: {
….
title: ‘Java’
},
App\Books: {
….
title: ‘How to use’
},

]
}

]
$authors = Author::with([‘books’ => fn($query) => $query->where(‘title’, ‘like’, ‘PHP%’)])
->whereHas(‘books’, fn ($query) =>
$query->where(‘title’, ‘like’, ‘PHP%’)
)
->get();

select * from authors WHERE EXISTS(SELECT * FROM authors WHERE authors.id = books.author_id and books.title like ‘PHP%’);
select * from books where `books`.`author_id` in (1, 5, 11, 22, 25, 27, 35, 39, 46, 62, ….) and books.title like ‘PHP%’);
[
App\Author : {
id: 1
name: “author 1”,
…,
books: [
App\Books: {
….
title: ‘PHP
},

]
},
App\Author : {
id: 2
name: “author 2”,
…,
books: [
App\Books: {
….
title: ‘PHP
},
App\Books: {
….
title: ‘PHP Laravel
},

]
}

]
```

public function scopeWithWhereHas($query, $relation, $constraint){
return $query->whereHas($relation, $constraint)
->with([$relation => $constraint]);
}

Author::withWhereHas(‘books’, fn($query) =>
$query->where(‘title’, ‘like’, ‘PHP%’)
)->get();

Select * from authors WHERE EXISTS(SELECT * FROM authors WHERE authors.id = books.author_id and books.title like ‘PHP%’);
Select * from books where `books`.`author_id` in (1, 5, 11, 22, 25, 27, 35, 39, 46, 62, ….) and books.title like ‘PHP%’);
use \Illuminate\Database\Eloquent\Builder\Eloquent;Eloquent::macro(‘withWhereHas’, fn($relation, $constraint) =>
$this->whereHas($relation, $constraint)
->with([$relation => $constraint]);
);

Full-Stack Web Developer