Home > OS >  How to chain where conditions with OR operator?
How to chain where conditions with OR operator?

Time:07-29

I need to retrieve all the posts which contains the following conditions as default: language, type, status.

Since this is a search system I need to check if the title or the content contains a specific search term, so I did:

 $posts = Post::where([
            ['language', '=', $locale],
            ['type', '=', 'post'],
            ['status', '=', 'publish'],
            ['title', 'LIKE', "%$s%"]
        ])
            ->orWhere('content', 'like', "%$s%")
            ->orderBy('date', 'desc')
            ->paginate(5);

now the problem is the following:

if the title contains the searched term, all the post with language, type and status are correctly returned. But the orWhere will return only the posts which match as content the searched term.

Is there a way to replicate language, type and status condition also in the orWhere clause without rewrite each time this: (?)

['language', '=', $locale],
['type', '=', 'post'],
['status', '=', 'publish'],

After a bit of playground the correct syntax is:

 $posts = Post::where([
            ['language', '=', $locale],
            ['type', '=', 'post'],
            ['status', '=', 'publish'],
        ])->where(function ($query) use ($s) {
            $query->where('title', 'LIKE', "%$s%")
                ->orWhere('content', 'LIKE', "%$s%");
        })
            ->orderBy('date', 'desc')
            ->paginate(5);

CodePudding user response:

You should group the searchterm fields in an orWhere which is part of the "and"Where. Sth. like this regarding the docs https://laravel.com/docs/9.x/queries#or-where-clauses

$posts = Post::where([
        ['language', '=', $locale],
        ['type', '=', 'post'],
        ['status', '=', 'publish'],
        function($query) {
            $query->orWhere([
                ['title', 'LIKE', "%$s%"],
                ['content', 'LIKE', "%$s%"]
            )
        }
    ])

CodePudding user response:

Try this one. Hope it will work.

  $post = Post::where(function ($query) use ($s) {
    return $query->where(
      ['language', '=', $locale],
      ['type', '=', 'post'],
      ['status', '=', 'publish']
    )->orWhere(
        ['title', 'LIKE', "%$s%"],
        ['content', 'LIKE', "%$s%"]
    )
  })->orderBy('date', 'desc')->paginate(5);
  • Related