I want to write more than one condition where in controller. How can I solve this? For example :
$query = $query->where(function ($q,$request) { $q->where('product_name', 'like', '%'.$request->get('q').'%')->orWhere('product_id','like', '%'.$request->get('q').'%')->get();});
$result = User::where(function($query) use ($search) {
$query->orWhere('product_name', 'LIKE', "%{$search}%")
->orWhere('product_id', 'LIKE', "%{$search}%");
})->get();
I hope it would work for you.
Related
I have some struggles with search method in controller. Functions must search in 2 tables, but it will search only in one, the first one. What could be proper approach here?
->when($search, function ($query) use ($search) {
$query->whereHas('info', static function (Builder $query) use ($search) {
$query->where('name', 'LIKE', "%{$search}%")
->orWhere('description', 'LIKE', "%{$search}%")
->orWhere('keywords', 'LIKE', "%{$search}%");
});
$query->whereHas('merchant.translation', static function (Builder $query) use ($search) {
$query->where('name', 'LIKE', "%{$search}%")
->orWhere('description', 'LIKE', "%{$search}%")
->orWhere('keywords', 'LIKE', "%{$search}%");
});
})
I tried with if statement if first one has null or undefined, but no success.Also I tried to separate when function.
Hi I have this code that is to search for records.
Admins are able to see all records, this is the query for admins
$trainings = Training::where('staffName', 'LIKE', "%{$request->search}%")
->orWhere('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%")
->paginate();
Whereas Employees should only see their records, so how do I add this condition into the existing query for the search function? This is the query I have for the Employee search currently
$employees = Training::where('staffName',$username)
->orWhere('staffName', 'LIKE', "%{$request->search}%")
->orWhere('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%")
->paginate();
I have another version for Managers, which is meant to also refer to their roles from a different table. I am trying it like this but it only is working properly when it comes to the Manager, but when the function fetches anything related to staff under them it fetches all records instead of specific records.
$managers = DB::table('trainings')
->join('users','users.id','=','trainings.staff_id')
->select('trainings.staffName','programTitle','trainer','trainingDate','hours')
->where('trainings.staffName',$username)
->orWhere('reportingTo',$username)
->where(function ($query) use ($request) {
$query->where('trainings.staffName', 'LIKE', "%{$request->search}%")
->orWhere('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%");
})
->paginate();
Your usage of orWhere is wrong because orWhere remove all conditions if it's true try this code below
Training::where('staffName', $username)
->where(function ($query) {
$query->where('staffName', 'LIKE', "%{$request->search}%")
->orWhere('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%");
})
->paginate();
For the last query
$managers = DB::table('trainings')
->join('users', 'users.id', '=', 'trainings.staff_id')
->select('trainings.staffName', 'programTitle', 'trainer', 'trainingDate', 'hours')
->where(function ($query) use ($username) {
$query->where('trainings.staffName', $username)
->orWhere('reportingTo', $username);
})
->where(function ($query) use ($request) {
$query->where('trainings.staffName', 'LIKE', "%{$request->search}%")
->orWhere('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%");
})
->paginate();
here's when query scopes comes to the rescue.
class Training extends Eloquent {
public function scopeFilterByRole($query, $roleId, $searchInput)
{
if ($roleId === 3) {
return $query->where('staffName', 'LIKE', "%{$searchInput}%")
}
return $query;
}
}
Then in your controller
Training::where('programTitle', 'LIKE', "%{$request->search}%")
->orWhere('trainer', 'LIKE', "%{$request->search}%")
->FilterByRole(3, $request->search)
->get();
You can write a global scope for that it will automatically apply in all existing queries:
protected static function boot()
{
parent::boot();
static::addGlobalScope(function (Builder $builder) {
if (auth()->check() and auth()->user()->role == 3) {
$builder->where('staffName', 'LIKE', "%{request()->get('search_name')}%")
}
});
}
On my website I am trying to implement search functionality. When someone enters keyword I am supposed to find all posts and users that may match that keyword based on posts title or body, or based on users name, username or bio. However I am having trouble with executing this query.
public function search(Request $request) {
$keyword = $request->get('q');
$posts = Post::where('deleted', 0)
->where('title', 'like', '%'.$keyword.'%')
->orWhere('body', 'like', '%'.$keyword.'%')
->orderBy('title')
->get();
$users = User::where('name', 'like', '%'.$keyword.'%')
->where('active', 1)
->orWhere('username', 'like', '%'.$keyword.'%')
->orWhere('bio', 'like', '%'.$keyword.'%')
->orderBy('username')
->get();
return view('searchresults', compact('users', 'posts'));
}
The specific problem I am having is that after function search $posts variable contains posts which were deleted.
This is what I actually need:
select * from posts where deleted = 0 and (title like $keyword or body like $keyword)
I appreciate any help.
Thanks. :)
Use closure to group where() and orWhere() like this:
$posts = Post::where('deleted', 0)
->where(function($q) use($keyword) {
$q->where('title', 'like', '%' . $keyword . '%')
->orWhere('body', 'like', '%' . $keyword . '%');
})
->orderBy('title')
->get();
public function search(Request $request) {
$keyword = $request->get('q');
$posts = Post::whereNull('deleted')
->where('title', 'like', '%'.$keyword.'%')
->orWhere('body', 'like', '%'.$keyword.'%')
->orderBy('title')
->get();
$users = User::where(function($query) use($keyword){
$query->where('name', 'like', '%'.$keyword.'%');
$query->orWhere('username', 'like', '%'.$keyword.'%');
$query->orWhere('bio', 'like', '%'.$keyword.'%');
})
->where('active', 1)
->orderBy('username')
->get();
return view('searchresults', compact('users', 'posts'));
}
Hope it's help you!!
I use Laravel 5.3
My code is like this :
public function getWishlist($param)
{
$num = 20;
$q = $param['q'];
$location = $param['location'];
$result = $this->product_repository->whereHas('favorites', function ($query) use($q, $location) {
$query->where('favorites.user_id', '=', auth()->user()->id)
->where('products.status', '=', 1);
if($q)
$query->where('products.name', 'like', "%$q%");
})
->join('stores', 'stores.id', '=', 'products.store_id');
if($location)
$result->where('stores.address', 'like', "%$location%");
if($q)
$result->where('products.name', 'like', "%$q%")
->where('stores.address', 'like', "%$q%", 'or');
dd($result->toSql());
// ->paginate($num);
return $result;
}
When executed, the result is empty
Seems wherehas and join not work simultaneously
Is there any solution to solve my problem?
I think you can use advanced where
$result = $result->where(function($query) use ($q) {
$query->where('products.name', 'like', "%$q%")
->where('stores.address', 'like', "%$q%", 'or');
})
This is my first attempt to build a search service. The problem is that the code I have looks very untidy, which will probably lead to other problems in the future. Here is what I have written so far:
<?php namespace Acme\Services\Search;
use Product, Brand;
class ProductSearchService {
public function search($data = array()) {
$limit = 10;
$query = isset($data) ? $data : "";
$baseQuery = Product::take($limit);
$brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();
if($query) {
if (!empty($brand)) {
return $baseQuery
->where('name', 'LIKE', '%'.$query.'%')
->orWhere('description', 'LIKE', '%'.$query.'%')
->orWhere('brand_id', 'LIKE', '%'.$brand->id.'%')->get();
}
return $baseQuery
->where('name', 'LIKE', '%'.$query.'%')
->orWhere('description', 'LIKE', '%'.$query.'%')->get();
}
}
}
How should I structure this service so that it will be cleaner and return more accurate results?
Solution
The answers posted here were very helpful but I found another solution to this.
I used eager loading to reduce the number of queries and declared a base query, like so:
$products = Product::with('brand')
->where('name','LIKE','%'.$term.'%');
while then I have used the orWhereHas method to search for any associated brands, like so:
$products->orWhereHas('brand', function($q) use ($term) {
$q->where('name', 'like', '%'.$term.'%');
});
and then return $products->get()
Here's my attempt
<?php namespace Acme\Services\Search;
use Product, Brand;
class ProductSearchService {
public function search($query) {
$limit = 10;
$brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();
$baseQuery = Product::take($limit)
->where('name', 'LIKE', '%'.$query.'%')
->orWhere('description', 'LIKE', '%'.$query.'%');
if (!empty($brand))
{
$baseQuery = $baseQuery->orWhere('brand_id', 'LIKE', '%'.$brand->id.'%')->get();
}
return $baseQuery->get();
}
}
Rewrote it for you, please note that this is not perfect yet, also using LIKE for the brand_id isn't really a smart idea as an id is unique! This also means that searching for the name and description isn't needed either. You should just search on id when you got the id, if not, execute the 2 LIKE queries.
<?php
namespace Acme\Services\Search;
use Product, Brand;
class ProductSearchService {
public function search($data = array()) {
$limit = 10;
$query = isset($data) ? $data : "";
$baseQuery = Product::take($limit);
$brand = Brand::where('name', 'LIKE', '%'.$query.'%')->first();
$brandId = !empty($brand) ? $brand->id : "";
return $baseQuery->where('name', 'LIKE', '%'.$query.'%')
->orWhere('description', 'LIKE', '%'.$query.'%')
->orWhere('brand_id', 'LIKE', '%'.$brand_id.'%')->get();
}
}
?>