1
votes

I'm trying to understand some advanced eloquent commands and on the Laravel official documentation, there is not so much about the Eloquent orWhereHas method and there isn't also an example about how it works.
https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

Can somebody help me to understand it with also a simple example?

2
Do you have any ambiguity about whereHas or just about orWhereHas?BABAK ASHRAFI
The signature is the same as whereHas.ml59

2 Answers

2
votes

How to use it: just chain as any other Eloquent method

User::whereHas(...)->orWhereHas(...)->get();

When to use it: imagine you have Users, Posts and Comments, and each user can write posts and comments. Then you need to get active users. For example, you assume active as user, who has made posts OR comments last 7 days. So, you can get it this way:

$users = App\Models\User::query()
    ->whereHas('posts', function (Builder $query) {
        $query->where('created_at', '>=', Carbon::now()->subDays(7));
    })
    ->orWhereHas('comments', function (Builder $query) {
        $query->where('created_at', '>=', Carbon::now()->subDays(7));
    })
    ->get();
2
votes

Say there's a blog kind of app. The main entity/model of the app would be Post (Blog Post).

When any author writes and publishes a Post,

  • visitors to the blog site can leave Comment(s) for the Post
  • visitors can Like a Post

So we have 3 models here

  • Post - which can have many Comment(s)
  • Post - can have many Like(s)

Now let's say for some reason we want to get all Post records from the database which either have 10 or more comments in the current month or 3 or more likes in the current month

We can write a query like

$posts = Post::whereHas('comments', function($query) {
        $query->where('created_at', '>', now()->startOfMonth();
    }, '>=', 10)
    ->orWhereHas('likes', function($query){
        $query->where('created_at', '> ', now()->startOfMonth();
    }, '>=', 3)
    ->get();

Laravel docs: https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence

Just like where both whereHas and orWhereHas accepts closure as 2nd argument for more fine grained query control.

Actually whereHas is supposed to be used when you want to have more power on constraints.

If you just want to check the existence of relation records you can use has for eg:

Get all post records which either have comment or like and paginate 20 per page

$postsWithCommentsOrLikes = Post::has('comments')
    ->orHas('likes')
    ->paginate(20);