How do I can select data to show based on comparation in yii2 Activerecord? My data record from db contain column depTime. So I want to show only data that has depTime less than current time.
Here is my function in my controller.
public function actionSelectedTeam($id) {
$searchModel = new TeamSearch();
$dataProvider= $searchModel->search(Yii::$app->request->queryParams);
$dataProvider->pagination = [
'pageSize' => 5
];
return $this->render('team-info', [
'model' => $this->findModel($id),
'dataProvider' => $dataProvider,
]);
}
Or there is another way to do that? I mean outside this method, maybe from the model.
Thankyou.
You will always have the records displayed that are smaller than the current time, other than they are some kind of reservations and you are providing future date/time manually.
You haven't specified what is the type of the depTime column, I assume that you have a datetime column, you can use the time() and now() function to achieve this.
You can add the following line in your search model's search() method before you return the $dataProvider which is subtracting the depTime from the current time and if the result is positive it will include the record.
$query->andFilterWhere(['>', new Expression('time(now()) - time(depTime)'), 0]);
Related
I have 3 models connected by simple one-to-many relationships:
One Client(has many) Points,
One Point (has many) order_powers. The order_powers table has value and date_from columns. date_from is the date from which the value of of the ordered power is valid.
In Client model:
public function points() {
return $this->hasMany(Point::class);
}
public function order_powers() {
return $this->hasManyThrough(OrderPower::class, Point::class);
}
In Point model:
public function clients() {
return $this->belongsTo(Client::class);
}
public function order_powers() {
return $this->hasMany(OrderPower::class);
}
In OrderPower model:
public function order_powers() {
return $this->belongsTo(Point::class);
}
I want to display on single page:
data of a single Client
data of Points belonging to this Client
Ordered power for each of the Client's Points. Only one value of Object with the most recent "date from" should be displayed.
My rendering ClientController with Inertia and Vue looks like this and actually points 1 and 2 are DONE, point 3 is a problem for me. Currently, the controller displays all ordered powers of a given Point. I don't know how to display only one value of column 'value' depending on the date_from column?
return Inertia::render('Clientshow', [
'client' => [
'id' => $client->id,
'name' => $client->name,
'street' => $client->street,
'city' => $client->city,
'points' => $client->points()->with(['order_powers'=>function ($q)
{
$q->orderBy('date_from','desc');
}
])->get(),
],
]);
Example:
one Client has two Points
each Point has two order_powers
Vue shows all two values for each of the points, I want just one (first(), take(1) shows only one order_power value for ALL Points.
My Vue component:
>client:Reactive
id:33
name:"ClientName"
street:"StreetName"
city:"CityName"
>points:Array[2]
>0:Object
client_id:33
created_at:"2022-10-13T15:31:37.000000Z"
id:65
>order_powers:Array[2] <- I want display only one value of column "value" of one Object
>0:Object
>1:Object
pp_type:"xxxx"
updated_at:"2022-10-13T15:31:37.000000Z"
>1:Object
I'm not sure to understant your problem, but i think that if you want to select just the value of column value in model Point you can use:
'points' => $client->points()->with(['order_powers:id,value'=>function ($q) ...
Am getting data from two tables banks one has bank details and another has cheques. the cheques table has bank_id column where by i loop through and calculate the totals of each bank.
How can i store the data in a table instead of it staying in a variable.
I have a controller to calculate the totals;
$banks_data = Bank::all();
$banks_totals = [];
foreach ($banks_data as $bank){
$totals = InsuranceCheque::where('bank_id', $bank->id)->sum('amount');
array_push($banks_totals,
[
'id'=>$bank->id,
'name'=> $bank->name,
'description' =>$bank->description,
'amount'=>$totals,
'created_at'=>$bank->created_at,
]);
}
but how will i be able to access the data in a different controller?
Which table do you want to save it to? Assuming you have a model BankTotal that handles the table bank_totals, you can do this
$banks_data = Bank::all();
$banks_totals = [];
foreach ($banks_data as $bank){
$totals = InsuranceCheque::where('bank_id', $bank->id)->sum('amount');
array_push($banks_totals,
[
'id'=>$bank->id,
'name'=> $bank->name,
'description' =>$bank->description,
'amount'=>$totals,
'created_at'=>$bank->created_at,
]);
}
BankTotal::insert($bank_totals);//Bulk insert
I did not understand the second part of the question on "but how will i be able to access the data in a different controller?"
But you can access the data from another controller by querying the model:
BankTotal::all();
So, i have a table called Items table and another table called item_quantities, on item_quantities ive a column named item_id which is connected to items table id. All the fillable properties on both tables are all in one form on the frontend, and i take care of the form fields on the backend
Whenever i try to update the quantity on the form which is from item_quantities's table with a form, i'm facing serious issue updating the item_quantities. getting Attempt to read property "item_id" on null.
It all started when i noticed a duplicate entries on the item-quantities table, so i deleted all the datas on it..
Here's is the form screenshot
The vue form
and the backend logic
public function saveData(Request $request, $id) {
// dd($request->name);
$updateGroceries = Item::where('id', $request->id)->get()->first();
$updateGroceries->update([
'name' => $request->name,
'description' => $request->description,
'price' => $request->price,
]);
if($updateGroceries) {
$item_quantity = ItemQuantity::where('item_id', $updateGroceries->id) ?
ItemQuantity::where('item_id', $updateGroceries->id)->get()->first() :
new ItemQuantity;
if($item_quantity->item_id == null) {
$item_quantity->item_id = $updateGroceries->id;
}
$item_quantity->quantity = $request->quantity;
$item_quantity->save();
}
}
I'M SO SORRY IF MY ENGLISH WAS'NT CLEARED ENOUGH
Thanks in anticipation
You can simply use firstOrNew() method. This will first find the item, if not exist create e new instance.
$item_quantity = ItemQuantity::firstOrNew(['item_id' => $updateGroceries->id]);
$item_quantity->quantity = $request->quantity;
$item_quantity->save();
Note that the model returned by firstOrNew() has not yet been persisted to the database. You will need to manually call the save method to persist it.
Actually your errors workflow as that:
$item_quantity=null;
$item_quantity->item_id;
You can do that with optional global helper:
optional($item_quantity)->item_id ?: 'default value';
i am trying to preform update or create action on many records using laravel model.
Normal insert with updateOrCreate works perfectly with foreach but i want to avoide it as it slowing things down.
I have something like 200k records.
Is there is any way to achive it?
I tried this answer below
https://stackoverflow.com/a/34815725/1239122
But it is not super elegant.
Any ideas?
You can try this library for batch insert and update.
https://github.com/mavinoo/laravelBatch
I didn't find a way to bulk insert or update in one query. But I have managed with only 3 queries. I have one table name shipping_costs. Here I want to update the shipping cost against the shipping area. I have only 5 columns in this table id, area_id, cost, created_at, updated_at.
// first get ids from table
$exist_ids = DB::table('shipping_costs')->pluck('area_id')->toArray();
// get requested ids
$requested_ids = $request->get('area_ids');
// get updatable ids
$updatable_ids = array_values(array_intersect($exist_ids, $requested_ids));
// get insertable ids
$insertable_ids = array_values(array_diff($requested_ids, $exist_ids));
// prepare data for insert
$data = collect();
foreach ($insertable_ids as $id) {
$data->push([
'area_id' => $id,
'cost' => $request->get('cost'),
'created_at' => now(),
'updated_at' => now()
]);
}
DB::table('shipping_costs')->insert($data->toArray());
// prepare for update
DB::table('shipping_costs')
->whereIn('area_id', $updatable_ids)
->update([
'cost' => $request->get('cost'),
'updated_at' => now()
]);
You can use insert() in Query Builder to bulk insert. But update statement needs conditions. Please read the document:
https://laravel.com/docs/5.7/eloquent#updates
As far as I know, you can not do it for the update as you need to check the condition for the update, But you can do it for insert
$data = array(
array('name'=>'John', 'phone'=>'1234567890'),
array('name'=>'Deo', 'phone'=>'9876543210'),
//...
);
Model::insert($data);
I'm using Fractal transformer in Laravel 5.6
I have a News Model and User Model. News model has a foreign key user_id. when I want to show list of News I transform the data like below:
public function transform(News $news)
{
return [
'identifier' => (int) $news->id,
'title' => (string) $news->title,
'content' => (string) $news->content,
'user' => (String) $news->user->f_name . " " . $news->user->l_name,
'userType' => (String) $news->user->user_type,
'likeCount' => (int) $news->likes,
];
}
And transform function is:
protected function transformData($data, NewsTransformer $transformer) {
$transformation = fractal($data, new $transformer);
return $transformation->toArray();
}
Now the problem is that when I transform the list of news it returns array instead of collection and after transformation I cant use operations like filtering the data by userType or sorting the data by user.
So how can I sort, filter and paginate the results by new fields after transformation?
You really should not be returning your own collection when using Fractals. You can use $this->collection($data) or $this->item($data) for single objects or entities.
Think of your transformer as your view. In MVC, you should not be making any calculations on your view (if you can help it), that is because the view is often repeated so any calculation will be repeated unnecessarily.
The logic you need belongs in your controllers.
https://fractal.thephpleague.com/resources/