Laravel, copy row to another table with eloquent relationship - php

I want to get the data form database table and create a new row in another table.
Which 1 PO have many PoProducts.
$_getPO = Order::find($id);
$_getPOProducts= OrderProducts::where('order_id', $id)->get();
$order_no = $_getPO->order_no;
$eta = $_getPO->eta;
$_Order = new DeliveryOrders();
$_Order->order_no = $order_no;
$_Order->eta = $eta;
$_Order->save();
$POProduct = array();
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[] = new DeliveryOrderProducts();
$POProduct[] = $_getPOProduct->order_id;
$POProduct[] = $_getPOProduct->item_id;
$POProduct[] = $_getPOProduct->qty;
$POProduct->save();
}
But, this output an error.
Call to a member function save() on array
Please help me. Thanks.

If you wish to copy records from one table to another or just duplicate a record in the same table you could simply use the repliacate() method.
$user = User::findOrFail($id);
// replicate (duplicate) the data
$staff = $user->replicate();
// make into array for mass assign.
//make sure you activate $guarded in your Staff model
$staff = $staff->toArray();
Staff::firstOrCreate($staff);
Note: in case you're only duplicating on the same table replace Staff with User on this example.

You are trying to run the save method on the array but what you want is to use it on the array index instead.
Change your foreach to this and it should work (assuming columns are the same).
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = new DeliveryOrderProducts();
$POProduct[$i]->order_id = $_getPOProduct->order_id;
$POProduct[$i]->item_id = $_getPOProduct->item_id;
$POProduct[$i]->qty = $_getPOProduct->qty;
$POProduct[$i]->save();
}
You can shorten this by using forceCreate.
foreach($_getPOProducts as $i => $_getPOProduct)
{
$POProduct[$i] = (new DeliveryOrderProducts())->forceCreate($_getPOProduct->only(['order_id', 'item_id', 'qty']));
}

Related

Why the name of trucks are same in 2nd and 3rd record of company data retrieval?

My data in database:
My objective is to retrieve all data of company collection (MongoDB) data from the database. The company collection holds one or many trucks. I have implemented one-to-many reference between company and trucks collection. That is working fine.
I am using query builder to get all the data. But, my code is not giving me all the Trucks of the specific company. It is retrieving only one truck name for specific documents.
My API code is checking the length of the truck's array and storing the name for the truck on ta[] array. Code is not written nicely as I have tried so many methods and I am frustrated now.
How can I retrieve my data?
My API:
/**
* #Route("/koco/get/company/query", name="queryToGetCompany")
* #Template()
*/
public function queryForCompanyAction()
{
$checkarray = array();
$dm = $this->get('doctrine_mongodb')->getManager();
$qb = $dm->createQueryBuilder(Company::class);
$qb->find(Company::class);
$query = $qb->getQuery();
$comapnies = $query->execute();
foreach ($comapnies as $company)
{
$objectId = $company->getId();
$objectName = $company->getName();
$objectAddress = $company->getAddress();
// for length
$len = count($company->getTrucks());
echo $len;
// For trucks
$Trucks = $company->getTrucks();
foreach ($Trucks as $truckname)
{
$ta = array();
for($i=0;$i< $len;$i++){
$object = new Truck();
$object = $truckname->getName();
$ta[] = $object;
}
}
$checkarray[] = array(
'Id' => $objectId,
'Name' =>$objectName,
'Address' =>$objectAddress,
'Trucks' => $ta,
);
}
$data = [
'Comapnies' => $checkarray,
];
return new JsonResponse($data);
}
My results from the API:
The 2nd and third companies are giving me the same records for the name of trucks, but in my database the truck names are different.
Your foreach and your for loop are colliding, in conjunction with your array being emptied inside the foreach loop. If you reset your array before the foreach loop, not inside, and also just use a foreach without the for, I think this is what you want.
What is happening in your code as presented in the question is that the array is wiped out between trucks, so you only get the last truck. Additionally, because of the manually counted for loop, the number of copies of the last truck is equal to the total number of trucks associated with each company.
This is my suggestion based on what you have shown, replacing the entire foreach loop with this code.
$ta = array();
foreach ($Trucks as $truckname)
{
$object = new Truck();
$object = $truckname->getName();
$ta[] = $object;
}

Improve performance of multiple row insertions in Laravel

I have a controller API method where I insert many rows (around 4000 - 8000), before inserting a new row I also check if a venue with the same ame was added already in the zone sothat's another Elouent call, my issue is I usually get timeout errors becuase the row inserting takes too much, I use set_time_limit(0) but this seems too hacky.
I think the key is the validation check I do before inserting a new row.
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
Is there a way I can improve the performance of this method ? This is my complete method call:
public function uploadIntoDatabase(Request $request)
{
set_time_limit(0);
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue)
{
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->first();
if(!$alreadyAdded)
{
$newVenue = new Venue();
$newVenue->name = $venue['name'];
$newVenue->save();
$count++;
}
}
return response()->json([
'message' => $count.' new venues uploaded to database',
]);
}
use only one request to add the venues
$newVenues = [];
$count = 0;
foreach($request->input('venuesToUpload') as $index => $venue) {
//Check if there is a venue with same name and in the same zone already added
$alreadyAdded = Venue::where('name', $venue['name'])->whereHas('address', function ($query) use ($address){
$query->where('provinceOrState' , $address['provinceOrState']);
})->orWhere('venueId',$venue['venueId'])->count();
if(!$alreadyAdded) {
$newVenues [] = ['name' => $venur['name'];
}
}
if ($newVenues) {
$count = count($newVenues);
Venue::insert($newVenues);
}
As for the verification part, change the first to count cause you dont need to recover the data, just the information that it exists. And since you're verifying with both name and id, you can do some custom query that verifies all values in one query using a static table made from the request inputs and joining on the existing venues table where venues.id = null.

Retrieving data from database using multiple ids - Laravel

I have list of clients in my database with with unique ids. I am trying to retrieve these customers using these unique ids like this .
I want to get each clients name and phone and so i can process a message to them respectively. But with my query, i am only getting only one client and not all of my clients.
PS: when i return $explode, i am able to get all the ids i have selected.
public function getCustomers(Request $request)
{
$ids = $request->ids;
$explode = explode(",",$ids);
if(request()->ajax())
{
$clients = Client::whereHas('product', function($find_clients)use($explode)
{
$find_clients->where('id',$explode);
})->get();
$get_customer_name = [];
$get_customer_phone = [];
foreach($clients as $key => $client)
{
$get_customer_name[] = $client->name;
$get_customer_phone [] = $client->phone;
return ['success' => $explode];
}
}
}
SMS query
$query = "?key=$api_keyto=$implode(',',$$get_customer_phone)&msg=Dear ".$implode(',',$$get_customer_name)."Thank you";
To find clients with an array of ids, try using whereIn instead of where.
Like so:
$find_clients->whereIn('id',$explode);
Try using whereIn instead of where
$find_clients->whereIn('id', $explode);

what is a good way to save an array data to mySQL in laravel

Its an online result marker. Once the user clicks save it gets the CA(Continious assessment) and it gets the Exam marks and the teachers remark for the particular student. I want to know how i can insert these fields into my database the right way.
return $request->all();
the above code returns the image below
$i = 0;
foreach($request->id as $id) {
$model = new Model;
$model->user_id = $id;
$model->ca_mark = $request->ca_mark[$i];
$model->exam_mark = $request->ca_mark[$i];
$model->remarks = $request->remarks[$i];
$model->save();
$i++;
}
Query Builder
$i = 0;
foreach($request->id as $id) {
DB::table('table')->insert([
'user_id' => $id,
'ca_mark' => $request->ca_mark[$i],
'exam_mark' => $request->ca_mark[$i],
'remarks' => $request->remarks[$i]
]);
$i++;
}
The above code has been written based on an assumption of the database table structure. In short, foreach on the ID's as this would be the student ID, and take the ca_mark, exam_mark and remark based on the key of the id.

Eloquent - Random from a existing list

I see that I can get a random row in Laravel 5 by:
Model::inRandomOrder()->get();
But I want to get all from Model and pick a random object from it like below.
$models = Model::all();
$model = $models->getRandom();
Any suggestion?
Yeah this should work:
$models = Model::all();
$model = $models->random();
Or even this:
$models = Model::get();
$model = $models->random();
two sugestions:
1. get your data twice:
$models = Model::all();
$model = Model::inRandomOrder()->get();
2. select a random row from the retrieved data:
$models = Model::all();
$model = $models[rand(0, count($models) - 1];

Categories