sfarzoso
sfarzoso

Reputation: 1600

How to chain where conditions with OR operator?

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);

Upvotes: 0

Views: 548

Answers (2)

Harish Patel
Harish Patel

Reputation: 84

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);

Upvotes: 0

dnaumann
dnaumann

Reputation: 474

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%"]
            )
        }
    ])

Upvotes: 3

Related Questions