Checking if column is null Laravel - laravel

I have this column ('time_out') in a table of my database:
As you can see the time_out is null, and when I do this query:
$checkertimeout = Attendance::where('emp_id', $request->emp_id)
->where('attend_date', $date)->get(['time_out']);
I get this output:
[{"time_out":null}]
But when I use it in an if-else statement:
if ($checkertimeout->isEmpty())
{
echo "works";
}
else
{
echo "wont work";
}
It display won't work.
Any help is appreciated, I'm new to Eloquent query :)

First of all, when you do this:
$checkertimeout = Attendance
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->get(['time_out']); // <---
You are getting a Collection of all the time_out fields of every Attendance models that match your criteria (the wheres). This means, something like this:
=> Illuminate\Database\Eloquent\Collection {#3323
all: [
App\Attendance {#3332
attend_date: "2019-10-06 22:01:29",
},
App\Attendance {#3340
attend_date: "2019-10-06 22:01:29",
},
App\Attendance {#314
attend_date: null,
},
],
}
You can get more info in the Eloquent section of the documentation.
Now, if your query is designed to get only one record, you could use the ->first() method instead of the get() one. This method will return the first Attendance object that matches your criteria.
$checkertimeout = Attendance
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->first(); // <---
PS: If you only need to retrieve the time_out value, you could also add the ->select('attend_date') to the query:
$checkertimeout = Attendance
->select('time_out'); // <---
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->first(); // <---
With these clarifications, let's go to your question. If you want to check if a field is null.. you could just make use of the PHP function is_null().
Using the collection
$checkertimeout = Attendance
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->get(['time_out']);
if(is_null($checkertimeout->first()->time_out))
{
// ...
}
Using a single object
$checkertimeout = Attendance
->select('time_out'); // <---
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->first(); // <---
if(is_null($checkertimeout->time_out)) // <----
{
// ...
}
Side note
As a side note, if you want to avoid the null results for that value, you could add another contraint in your query:
$checkertimeout = Attendance
::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->whereNotNull('time_out') // <-----
->get(['time_out']);

Hit it
$checkertimeout = Attendance::where('emp_id', $request->emp_id)
->where('attend_date', $date)->first();
At Blade File If Else
{{ $checkertimeout->time_out !=null ? 'Wont Work' : 'work' }} // when this condition $checkertimeout->time_out !=null true its run after "?" when its false it's running after ":" term
For Controller You can also dd or echo like below :
echo $checkertimeout->time_out !=null ? 'Wont Work' : 'work'; // you can replace echo with return too

First your query is getting all the records.
you should do like this in your query:
$checkerTimeOut = Attendance
::where([['emp_id', $request->emp_id], ['attend_date', $date]])
->first();
// This is to get a single record
then if you use if else statement you should also call the column you want to stablish.
if($checkerTimeOut->time_out->isEmpty()
{
dd('not empty');
}
else
{
dd('this record is empty');
}
you can also do like this:
if($checkerTimeOut->time_out)
{
dd('not empty');
}
else
{
dd('this record is empty');
}
or should be like this:
$checkerTimeOut->time_out
? 'not empty'
: 'this record is empty';

Event of the time_out is null, $checkertimeout variable is not empty. Because $checkertimeout is a collection. and it has one item in it.
As you can see like this.
[
{"time_out":null}
]
Since I don't know what you are trying to do, If you want the Attendance only where time_out is not null, You can do this.
$checkertimeout = Attendance::where('emp_id', $request->emp_id)
->where('attend_date', $date)
->whereNotNull('time_out')
->get(['time_out']);

Because $checkertimeout got a collection as
[
{"time_out":null}
]
so its no longer empty and it returns
"wont work"

Related

Filter an array list result from query builder in model in Laravel

I have a query function in my model to get list user and it return an array data to my repository class:
Model.php:
public function getUser()
{
return $this->select("{$this->table}.'*'")
->get();
}
Here is an example for the data:
[
[
"user_id":1,
"fullname":"amdv",
"is_active":0
],
[
"user_id":2,
"fullname":"abc",
"is_active":1
],
[
"user_id":3,
"fullname":"zyz",
"is_active":1
]
]
Now I want to check if is_active = 1, it continue check that user with other condition in other query
In my model, I have another query function with param is user id
Model.php:
public function checkUserAvailable($userId)
{
return $this->select("{$this->table}.'*'")
->join('other_table', 'join-condition')
->where('user_id', $userId)
->get();
}
But this function return data too, I don't know how to check this.
Thank you very much!
$data = [
[
"user_id":1,
"fullname":"amdv",
"is_active":1
],
[
"user_id":2,
"fullname":"abc",
"is_active":1
],
[
"user_id":3,
"fullname":"zyz",
"is_active":1
]
];
$filtered = collect($data)->filter(function($user) {
return User::someMethodYouMentioned($user['user_id']);
});
From what I understand is that you want to check the data from the array returned by the first function and if is_active = 1 then you want to check if the user is available via the second function in your model
//Get the user_id of records where is_active === 1
$available = collect($data)
->reject(fn($user) => $user['is_active'] !== 1)
->pluck('user_id')
->map(fn($id) => User::checkUserAvailable($id));
For this to work the checkUserAvailable needs to be a static function.
However looking at both the functions - question arises why do you need to run multiple database queries to check for user available via the second function.
You can modify the query in the second function to check for is_active
public static function checkUserAvailable()
{
return static::query()
->join('other_table', 'join-condition')
->where('is_active', 1)
->get();
}
Or if you still want to first get a list of all users as array and then check for availability, you could define the checkUserAvailable as a scope on the model
public function scopeCheckUserAvailable($query, $id)
{
$ids = Arr::wrap($id);
return $query->join('other_table', 'join-condition')
->whereIn('user_id', $ids);
}
Then you can get the data from the getUser() function and perform the second check like
//Get the user_id of records where is_active === 1
$checkIds = collect($data)
->reject(fn($user) => $user['is_active'] !== 1)
->pluck('user_id')
->all();
$availableUsers = User::checkAvailableUsers($checkIds)->get();
If you want to filter out the ones that are not active you can use array_filter with a callback:
$filtered = array_filter($array, fn ($i) => $i['is_active']);
If you want to use those values to call a function and then get those results you can use array_map:
$res = array_map([$this, 'checkUserAvailable'], array_column($filtered, 'user_id'));
You can also do this with the Collection methods if you would like:
collect($array)->where('is_active', 1)
->pluck('user_id')
->map([$this, 'checkUserAvailable'])
Though, I am not sure what else you need to be checking besides that is_active is true.

How to remove item from laravel query result and get it?

In Laravel project I am making a database query
$addresses = DB::table('residences')->where('user_id', '=', Auth::user()->id)->get();
I want to get one address from that query result, if it exists, where 'id' field equals to 10 for example. But I want to remove that address from $addresses query result simultaneously. Is there a simple way to do that?
You can use the reject() method on the $addresses collection, i.e:
$my_result = false;
$addresses = $addresses->reject(function ($value, $key) use (&$my_result) {
if($value->id == 10){
$my_result = $value;
return true
}
return false;
});

How To Retrieve the Second to Last Row of the Provided ID

How can I retrieve the second to last row of the id provided?
public function show($id)
{
if (! Gate::allows('backup_view')) {
return abort(401);
}
$backup = Backup::findOrFail($id);
$second = Backup::select('id')->union($backup)->where('id', '<=' , $backup->id);
dd($second);
return view('admin.backups.show', compact('backup', 'secondlast'));
}
Please help.
I assume you are trying to return the variable $second. You are returning a variable called 'secondlast'. Try changing the name of the variable to $secondlast.
In order to return the second last record from the Backup Model, the following query should work assuming your primary key is 'id':
Backup::orderBy('id', 'desc')
->skip(1)
->take(1)
->first();

Laravel : orWhere Search query

I have a simple query in my model to get data. Now I want to search with companyname.My query code:
$searchablePost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->whereIn('status',$is_or_active)
->whereIn('product_id', $userApprovalProductIDs)
->whereIn('demand_or_supply', $is_demand_supply)
->offset($offset)->limit($limit)
->orderBy('id','desc');
Now, I got 6 rows in this 6 rows I want to filter data with companyname which i get with comma separated abcCompany,indCompany.
array:2 [
0 => "abccompany"
1 => "indcompany"
]
What I try :
if($companyname !="") {
$companyDetail = Explode(',',$companyname);
$searchablePost->whereHas('user.userDetails', function ($query) use ($companyDetail) {
$i=1;
foreach ($companyDetail as $search_with_compayname) {
if(count($companyDetail)>0 && $i==1) {
$query->where('company','LIKE',"%{$search_with_compayname}%");
} else {
$query->orWhere('company','LIKE',"%{$search_with_compayname}%");
}
$i++;
}
});
}
Is it good or is there any other way to good search ?
If you want to search a CSV list of company names, MySQL makes available a function FIND_IN_SET. I think you can just add a whereRaw clause to your current Laravel query:
$searchablePost = Post::with(['product','postattribute.attribute.category','user.userDetails'])
->whereIn('status', $is_or_active)
->whereIn('product_id', $userApprovalProductIDs)
->whereIn('demand_or_supply', $is_demand_supply)
->whereRaw('FIND_IN_SET(company, ?) > 0', [$search_with_compayname])
->offset($offset)
->limit($limit)
->orderBy('id', 'desc');
While the above may work, the best long term approach is to avoid CSV and other unnormalized data in your database. Ideally, you would have a table containing the list of company names, with one name on each record. Then, you could join or use an EXISTS query to answer your question.

Delete query that has the very last date in laravel

I have a scenario where the record is like this:
date
2018-01-15
2018-01-16
Now what I need to do is just delete the very last date. I need to delete the query that has 2018-01-15.
My code is like this:
public function deletelatDate()
{
// $datedel = '2018-04-03';
$datedel = Attendance::sortBy('date', 'desc')->first();
// $query->sortBy('date', 'desc')->first();
DB::table('attendances')->where('date', $datedel )->delete();
return back()->with('success','Last attendance entries successfully deleted');
}
Do you have any suggestions on how am I able to fix this?
Thanks.
Use orderBy and get column date after getting first record
public function deletelatDate()
{
$datedel = Attendance::orderBy('date', 'asc')->first();
DB::table('attendances')->where('date', $datedel->date )->delete();
return back()->with('success','Last attendance entries successfully deleted');
}
Also check success of query before sending success message
You can use latest to get the latest record: https://laravel.com/docs/5.5/queries#ordering-grouping-limit-and-offset
public function deleteLatest()
{
// $datedel = today()->format('Y-m-d'); <-- use today's date
$datedel = '2018-04-03';
// find the record to delete
$toDelete = Attendance::where('date', $datedel)->oldest('date')->first();
// only perform delete if a record is found
if($toDelete) {
$toDelete->delete();
return back()->with('success','Last attendance entries successfully deleted');
}
return back()->with('error', 'No attendance entry found for this date: ' . $datedel);
}

Resources