Laravel Eloquent when date condition - laravel

I have an eloquent query, and inside it I have 2 condition. The first is when attendance_time == today and second is attendance_time == yesterday. I want to use that condition but I don't know how.
I've tried like code bellow, but still not working.
Attendance::where('employee_id', $request->employee_id)
->where('in_out', 'in')
->when('attendance_time' == Carbon::today(), function ($q) {
return $q->where('attendance_time', Carbon::today());
})->when('attendance_time' == Carbon::yesterday(), function ($q) {
return $q->where('attendance_time', Carbon::yesterday());
})->first();
Format for attendance_time is Y-m-d H:i:s

You can use whereBetween method:
use Carbon/Carbon;
...
Attendance::where('employee_id', $request->employee_id)
->where('in_out', 'in')
->whereBetween('attendance_time', [
Carbon::now()->subDay()->toDateString(),
Carbon::now()->toDateString()
])->first();

You can use whereDate, here is additional info. However, your query needs some improvement. If you use when it is like an if statement. It checks your condition and if it is true then add query inside of its function.
If you create something like that:
Attendance::where('employee_id', $request->employee_id)
->where('in_out', 'in')
->when($request->attendace_time, function ($q) {
return $q->where('attendance_time', Carbon::today());
})
That means if your request has attendace_time then add where query.
Or If you want to just filter todays attandees then you can use:
Attendance::where('employee_id', $request->employee_id)
->where('in_out', 'in')
->whereDate('attendance_time', Carbon::today()->format('Y-m-d'));

Related

Laravel, eloquent, query: problem with retriving right data from DB

I'm trying to get the right data from the database, I'm retriving a model with a media relation via eloquent, but I want to return a photo that contains the 'main' tag stored in JSON, if this tag is missing, then I would like to return the first photo assigned to this model.
how i assign tags to media
I had 3 ideas:
Use orWhere() method, but i want more likely 'xor' than 'or'
$models = Model::with(['media' => function ($query) {
$query->whereJsonContains('custom_properties->tags', 'main')->orWhere();
}]);
return $models->paginate(self::PER_PAGE);
Raw SQL, but i don't really know how to do this i tried something with JSON_EXTRACT and IF/ELSE statement, but it was to hard for me and it was a disaster
Last idea was to make 2 queries and just add media from second query if there is no tag 'main'
$models = Model::with(['media' => function ($query) {
$query->whereJsonContains('custom_properties->tags', 'main');
}]);
$models_all_media = Model:: with(['media']);
return $models->paginate(self::PER_PAGE);
but i tried something like
for($i=0; $i<count($models); $i++) {
$models->media = $models_all_media
}
but i can't do this without get() method, beacuse i don't know how to change this to LengthAwarePaginator class after using get()
try using whereHas https://laravel.com/docs/9.x/eloquent-relationships
Model::with('media')
->whereHas('media',fn($media)=>$media->whereJsonContains('custom_properties->tags', 'main'))
->paginate(self::PER_PAGE);
as per your comment you can use
$models = Model::with(['media' => function ($query) {
$query->whereJsonContains('custom_properties->tags', 'main');
}])
->leftJoin('media', function ($join) {
$join->on('models.id', '=', 'media.model_id')
->whereNull('media.custom_properties->tags->main');
})
->groupBy('models.id')
->paginate(self::PER_PAGE);
return $models;

how to use whereHas in laravel

I am new to laravel,
I need to create a query for the db,
$query = Deal::query();
I want to use the wherehas operator.
this is my code that is worked.
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus);
// \Log::info('The request precedence: '.$precedenceStatus);
}
I want to add this code also to the query
if($person) {
$query->whereHas('personnel', function ($subQuery) use ($person) {
$subQuery->where('id', '=', $person);
});
}
So I need to change the first code?
how I can convert the first code to wherehas?
the first code is from table called deal, the second section is from realtionship called personnel.
the second section worked in other places in the code, I just need to fix the first section and not understand what to write in the use
I try this and get error on the last }
else if ($group_by == 'precedence') {
if($get_deals_for == 'noprecedence'){
$get_deals_for = 0;
}
$precedenceStatus = $get_deals_for;
$query-> where('precedence', '=', $precedenceStatus)
-> when ($person, function($query) use($person) {
$query->whereHas('personnel', function ($query) use ($person) {
$query->where('id', '=', $person);
});
})
}
There is a method you can use called when(, so that you can have cleaner code. The first parameter if true will execute your conditional statement.
https://laravel.com/docs/9.x/queries#conditional-clauses
$result = $query
->where('precedence', '=', $precedenceStatus)
->when($person, function ($query) use ($person) {
$query->whereHas('personnel', fn ($q) => $q->where('id', '=', $person));
})
->get();
You should also be able to clean up your precedence code prior to that using when( to make the entire thing a bit cleaner.
Querying to DB is so easy in laravel you just need to what you want what query you want execute after that you just have to replace it with laravel helpers.Or you can write the raw query if you cant understand which function to use.
using,DB::raw('write your sql query').
Now Most of the time whereHad is used to filter the data of the particular model.
Prefer this link,[Laravel official doc for queries][1] like if you have 1 to m relation ship so u can retrive many object from one part or one part from many object.like i want to filter many comments done by a user,then i will right like this.
$comments = Comment::whereHas('user', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
$comments = Here will be the model which you want to retrive::whereHas('relationship name', function (Builder $query) {
$query->where('content', 'like', 'title%');
})->get();
you can also write whereHas inside whereHas.
[1]: https://laravel.com/docs/9.x/eloquent-relationships#querying-relationship-existence

Apply conditions using closure on Laravel Model collection

I am using Laravel Model collection and want to filter the records
in the first statement, I am checking that I only check the ends when it's has some date otherwise doesn't compare the value.
How to check the null value in this collection?
2nd if is working properly. I also used the filter method but it's not working for me. Can anyone suggest to me how to do this in a proper laravel way? I know I can do this using for each loop but I want to make the query faster. Please suggest your answers. Thank you
$subscriptionsCount = Subscription::where( function($query) {
if($query->where('ends_at', '!=' , null)){
$query->where('ends_at', '>=', now());
}
else if($query->where('subscription_ends_at', '>=', now())){
$query->where('subscription_ends_at', '>=', now());
}
})->where('name', $betTypeName)->count();
Can you try this code as I understood from your question you need whereNotNull
$subscriptionsCount = Subscription::where(function ($query) {
$query->where(function ($query) {
$query->whereNotNull('ends_at')->where('ends_at', '>=', now());
})->orWhere(function ($query) {
$query->whereNotNull('subscription_ends_at')
->where('subscription_ends_at', '>=', now());
});
})->where('name', $betTypeName)->count();
You can try with below whereRaw condition :
$subscriptionsCount = Subscription::where( function($query) {
$query->whereRaw("(CASE WHEN ends_at is not null THEN ends_at = now() WHEN subscription_ends_at >= now() THEN subscription_ends_at >= now() END)" );
})->where('name', $betTypeName)->count();
Hope Above code will be help you. Code is not tested but logic will help you. :)

How to write a query conditionally in laravel?

I am new to the laravel, i am joining three tables based on conditions every thing is working fine but i need to write conditionally if the $field is array it should run with whereIn otherwise it should run where condition,can you please help me to acheive this thing
//$field sometimes it's an array sometimes it's a string.
public function find($field){
}
For conditional constraints, you can use the when() clause:
$query = DB::table(...);
$data = $query
->when(is_array($field), function ($query) use ($field) {
$query->whereIn('my_field', $field);
}, function ($query) use ($field) {
$query->where('my_field', $field);
})
->get();
Now, as a tip, you could do this: Wrap the $fields variables to an array and then use always the whereIn clause. You can achieve this with the Arr::wrap() function:
use Illuminate\Support\Arr;
// ...
$query = DB::table(...);
$data = $query
->whereIn('my_field', Arr::wrap($field))
->get();
PS: I have linked the relevant functions to the docs so you can know how they work and their params.

laravel - send a selected field to with function

how can i use "airpot_id" in with function?
City::select([
"cities.id",
"airports.id As airport_id"
])
->RightJoin('airports', function ($join)
{
$join->on('cities.id', '=', 'airports.city_id');
})
->with(["airports" => function ($q)
{
$q->where("id",airport_id) //I want to use here.
}])
->paginate(env("PER_PAGE", 10))->toArray();
Why are you using joints like this? Use the eloquent query builder. Maybe you should post you modal, relations and your objective. In general, if we need to pass value inside function we use use($variable). Something like this
$airport_id = 1;
$data = City::with(["airports" => function ($q) use($airport_id){ //Like this we pass data
$q->where("id",airport_id)
}])->get();
I don't think this will work in your case

Resources