How can i create a conditional check in laravel query - laravel

hi how can we implement a condition checks in laravel query builder
$flag_email =true;
$query = DB::table('customer');
if($flag_email) {
$query->where('email','=',$email);
}
if(!$flag_email) {
$query->where('mobile','=',$email);
}
$query->get();

use when method here to check condition see
$query = DB::table('customer')
->when($flag_email, function ($query,$email) {
return $query->where('email', $email);
})
->when(!$flag_email, function ($query,$email) {
return $query->where('mobile', $email);
})->get();

you can use ->when to do conditional check
$query = DB::table('customer')
->when($flag_email, function ($query, $email) {
return $query->where('email', $email);
})
->when(!$flag_email, function ($query, $email) {
return $query->where('mobile', $email);
})->get();

Ternary operator to the rescue:
$query = DB::table('customer')->where($flag_email?'email':'mobile',$email);

You can try by this way. This way will outputs your desire one. This just a way, I am not sure, this one is the proper way.
$flag_email =true;
$query = DB::table('customer');
if($flag_email)
$query = $query->where('email','=',$email);
if(!$flag_email)
$query = $query->where('mobile','=',$email);
$result= $query->get();

Related

How to apply filter conditions gradually without breaking the previous filtering conditions

Maybe this question seems stupid but I need to learn how it is possible to fix it.
In Laravel, I try to apply many conditions according to users choices, like this:
$query = Model::query();
if ($request->has('ids')) {
$query = $query->whereIn('id', $request->get('ids'));
}
if ( ($request->has('fruits')) ) {
$query = $query->whereHas('fruits', function ($sQuery) use ($list) {
$sQuery->whereIn('fruit.id', $list);
});
}
if ($request->has('date')) {
$query = $query->whereDate('created_at', '>=', $request->get('date'))
->orWhereDate('updated_at', '>=', $request->get('date'));
}
The fact is the conditions about dates break previous filter conditions. I am getting other raws which do not match to first conditions. I guess it is because orWhereDate which is applied as condition "or" about all others. How to deal with this?
I found it. I prefer answer my own question than delete it.
$query = Model::query();
if ($request->has('ids')) {
$query = $query->whereIn('id', $request->get('ids'));
}
if ( ($request->has('fruits')) ) {
$query = $query->whereHas('fruits', function ($sQuery) use ($list) {
$sQuery->whereIn('fruit.id', $list);
});
}
if ($request->has('date')) {
$date = $request->get('date');
$query->where(function($query) use ($date){
$query->whereDate('created_at', '>=', $date)
->orWhereDate('updated_at', '>=', $date);
});
}
Hope this could help quickly someone.

Laravel filter of multiple variables from multiple models

Goodmorning
I'm trying to make a filter with multiple variables for example I want to filter my products on category (for example 'fruit') and then I want to filter on tag (for example 'sale') so as a result I get all my fruits that are on sale. I managed to write seperate filters in laravel for both category and tag, but if I leave them both active in my productsController they go against eachother. I think I have to write one function with if/else-statement but I don't know where to start. Can somebody help me with this please?
These are my functions in my productsController:
public function productsPerTag($id){
$tags = Tag::all();
$products = Product::with(['category','tag','photo'])->where(['tag_id','category_id'] ,'=', $id)->get();
return view('admin.products.index',compact('products','tags'));
}
public function productsPerCategory($id){
$categories = Category::all(); //om het speciefieke id op te vangen heb ik alle categories nodig
$products = Product::with(['category','tag','photo'])->where('category_id', '=', $id)->get();
return view('admin.products.index',compact('products','categories'));
}
These are my routes in web.php. I guess this will also have to change:
Route::get('admin/products/tag/{id}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Route::get('admin/products/category/{id}','AdminProductsController#productsPerCategory')->name('admin.productsPerCategory');
For filter both
change your URL like
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');
Make your function into the controller like
public function productsPerTag($tagId = null, $categoryId = null){
$tags = Tag::all();
$categories = Category::all();
$query = Product::with(['category','tag','photo']);
if ($tagId) {
$query->where(['tag_id'] ,'=', $tagId);
}
if ($tagId) {
$query->where(['category_id'] ,'=', $categoryId);
}
$products = $query->get();
return view('admin.products.index',compact('products','tags', 'categories'));
}
You are trying to filter in your query but you pass only 1 parameter to your controller, which is not working.
1) You need to add your filters as query params in the URL, so your url will look like:
admin/products/tag/1?category_id=2
Query parameters are NOT to be put in the web.php. You use them like above when you use the URL and are optional.
2) Change your controller to accept filters:
public function productsPerTag(Request $request)
{
$categoryId = $request->input('category_id', '');
$tags = Tag::all();
$products = Product::with(['category', 'tag', 'photo'])
->where('tag_id', '=', $request->route()->parameter('id'))
->when((! empty($categoryId)), function (Builder $q) use ($categoryId) {
return $q->where('category_id', '=', $categoryId);
})
->get();
return view('admin.products.index', compact('products', 'tags'));
}
Keep in mind that while {id} is a $request->route()->parameter('id')
the query parameters are handled as $request->input('category_id') to retrieve them in controller.
Hope It will give you all you expected outcome if any modification needed let me know:
public function productList($tag_id = null , $category_id = null){
$tags = Tag::all();
$categories = Category::all();
if($tag_id && $category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->where('category_id' , $category_id)
->get();
} elseif($tag_id && !$category_id) {
$products = Product::with(['category','tag','photo'])
->where('tag_id' , $tag_id)
->get();
} elseif($category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->where('category_id' , $category_id)
->get();
} elseif(!$category_id && !$tag_id) {
$products = Product::with(['category','tag','photo'])
->get();
}
return view('admin.products.index',compact(['products','tags','products']));
}
Route:
Route::get('admin/products/tag/{tag_id?}/{category_id?}','AdminProductsController#productsPerTag')->name('admin.productsPerTag');

I can't use variable in a function whereHas

I'm new with laravel. I can't use $class _id in a function whereHas. What should I do?
public function show($classroom_id)
{
$classrooms = Group::whereHas('members', function ($query) {
$query->where([['user_id', '=', Auth::id()], ['classroom_id', $classroom_id]]);
})->get();
return response()->json($classrooms);
}
See use (classroom_id)
$groups = Group::whereHas('natures', function($q) use($classroom_id)
{
$q->where('classroom_id', '=', $classroom_id);
});

Laravel - passing array of columns in 'where' clause

I have a search query like this:
$data = User::where('first_name', 'like', '%'.$query.'%')
->orWhere('last_name', 'like', '%'.$query.'%')
->get();
Now, I have many models, each with different column names. Instead of defining a search() function into every controller, I want to do this:
// User
public static function searchableFields()
{
return ['first_name', 'last_name'];
}
// Some other model
public static function searchableFields()
{
return ['name', 'description'];
}
And put the search logic in a shared controller, something like this:
$data = $classname::
where($classname::searchableFields(), 'like', '%'.$query.'%')
->get();
How can I achieve this?
Thanks a lot.
You can loop over the fields and add them to your Eloquent query one by one.
$data = $classname::where(function ($query) use ($classname) {
foreach ($classname::searchableFields() as $field)
$query->orWhere($field, 'like', '%' . $query . '%');
})->get();
I would use scope for that.
You can create base model that all the models should extend (and this model should extend Eloquent model) and in this model you should add such method:
public function scopeMatchingSearch($query, $string)
{
$query->where(function($q) use ($string) {
foreach (static::searchableFields() as $field) {
$q->orWhere($field, 'LIKE', '%'.$string.'%');
}
});
}
Now you can make a search like this:
$data = User::matchingSearch($query)->get();
Just to avoid confusion - $query parameter passed to matchingSearch becomes $string parameter in this method.
You can try something like this.
// Controller
function getIndex(Request $request)
{
$this->data['users'] = User::orderBy('first_name','asc')->get();
if ($request->has('keyword')) {
$results = User::search($request->keyword);
$this->data['users'] = collect([$results])->collapse()->sortBy('first_name');
}
}
// Model
function search($keyword)
{
$results = [];
$search_list = ['first_name','last_name'];
foreach ($search_list as $value)
{
$search_data = User::where($value,'LIKE','%'.$keyword.'%')->get();
foreach ($search_data as $search_value) {
$exist = 0;
if (count($results)) {
foreach ($results as $v) {
if ($search_value->id == $v->id) {
$exist++;
}
}
if ($exist == 0) {
$results[] = $search_value;
}
} else{
$results[] = $search_value;
}
}
}
return $results;
}

How do I use < or > in where clauses on collection in Laravel 5.1

How do I use < or > in where clauses on collection in Laravel? The below is not working:
$company['jobs']->where('created_at','>=',$Start_Date)->where('created_at','<=',$End_Date)
Use the orWhere method:
$company['jobs']->where('created_at', '>=', $Start_Date)
->orWhere('created_at', '<=', $End_Date);
Alternatively, you can use the whereBetween method:
$company['jobs']->whereBetween('created_at', [$Start_Date, $End_Date]);
This is the right solution
$filtered = $company['jobs']->filter(function ($item) use($Start_Date,$End_Date) {
error_log($item['created_at']);
return $item['created_at'] >= $Start_Date && $item['created_at'] <= $End_Date;
});
As #Joseph Silber said, you can create a Scope in your Model to do your own logic. Like this:
// Inside your model
public function scopeSearch($query, $field, $value)
{
if(is_numeric($value))
return $query->where($field, '=', "$value");
elseif(!empty($value))
return $query->where($field, '=', "$value");
else
return $query;
}
Then, you can call it from your controller:
$query = Company::search('year',2016);

Resources