I need to save multiple rows with the different condition for each row.
Like :
Update orderdetails SET data = "'.$json1.'" WHERE order_id = 1;
Update orderdetails SET data = "'.$json2.'" WHERE order_id = 2;
Update orderdetails SET data = "'.$json3.'" WHERE order_id = 3;
Update orderdetails SET data = "'.$json4.'" WHERE order_id = 4;
Update orderdetails SET data = "'.$json5.'" WHERE order_id = 5;
I know the single row updation method of CakePHP, that I can run 5 times form to update all row.
But I want to save this by just only one line code that can run above query.
My Code
$update = array(
array('data' => $json1,'order_id' => 1),
array('data' => $json2,'order_id' => 2),
array('data' => $json3,'order_id' => 3),
array('data' => $json4,'order_id' => 4),
array('data' => $json5,'order_id' => 5)
);
$this->Orderdetail->saveMany($update);
So, is there any way in CakePHP to achieve it...?
If I understand the above problem currently, you can achieve this by using the saveMany function in cakePHP. All you have to do is convert the data that you want to save in the form of an array and pass that single array to the saveMany function.
See here for more details
Here is a code sample for the above details in cakePHP 3:
$saveData = [
[
'order_id' => 1,
'data' => $json1
],
[
'order_id' => 2,
'data' => $json2
],
[
'order_id' => 3,
'data' => $json3
],
[
'order_id' => 4,
'data' => $json4
],
[
'order_id' => 5,
'data' => $json5
]
];
$orderDetails = TableRegistry::get('Orderdetails');
$entities = $orderDetails->newEntities($saveData);
$result = $orderDetails->saveMany($entities);
For cakePHP 2.x:
See here for more details
Hope this is what you are looking for.
Edit: Based on the updated requirements, I guess the only way to achieve it is to make a custom query by using the Model->query method. You'll have to form a custom query for that which updates all the records in one go.
Related
I got this:
$arr = json_decode($arr, TRUE);
while($row){
// $arr[] = ['id' => '8', 'name' => 'mickey'];
$test = $row->TCI_LIBELLE;
$arr[] = ['id' => $row->TCI_ID, 'name' => $row->TCI_LIBELLE];
$i +=1;
$row = $reqCentreInteret->fetch(PDO::FETCH_OBJ);
$json = json_encode($arr);
If you don't understand I'm trying to put values I get from a Select SQL query into a JSON array.
The problem is that it does't work like I want.
Indeed it works with my id because in my database it's an int value, but it does't work for the name because it is a varchar value
This is what i want to obtain :
[{"id":"8","name":"mickey"},{"id":"8","name":"mickey"}]
And here 'mickey' will be replaced by the value of my php string that will be initialized by my sql query
I already tried to solve my problem using
'name' => '" .$row->TCI_LIBELLE."'
But it does't work
How can I pass string value (or other type) to my JSON array?
I'm using PHP and JSON to send value from MySQL to an Android app.
arr[] = adds a new row to the array, i.e. a new top-level element.
You probably want to add your data to the existing element
Let's say your arr initially is something like
[ 'property1' => 'value1',
'property2' => 'value2'
...]
when you're doing
arr[] = ['id'=> 8,'name' => 'mickey']
your array will now contain 2 top level elements and look like
[[ 'property1' => 'value1',
'property2' => 'value2'
...
],
[ 'id' => 8,
'name' => 'mickey'
]
]
you may want to do this instead
arr['id'] = $row->TCI_ID;
arr['name'] = $row->TCI_LIBELLE;
then your arr will look like this:
[ 'property1' => 'value1',
'property2' => 'value2'
'id' => 8
'name' => 'mickey'
...
]
Finally this is what is had to do
$stmt = $db->query("SELECT TCI_ID AS id, TCI_LIBELLE AS nom FROM
OSO_DEV.T_CENTRE_INTERET");
echo json_encode($stmt->fetchAll(PDO:: FETCH_ASSOC),JSON_UNESCAPED_UNICODE);
Method 1 : Here I wrote the code for insert booking seat data into the database
Problem : When I book new seat it will creating new row so I'm getting duplicate rows so I tried method 2
Method 1 code :
$booking = new Bookings();
$booking->users_id = 4;
$booking->schedules_id = $schedules_id;
$booking->buses_id = $buses_id;
$booking->routes_id = $routes_id;
$booking->seat = implode(',', $seat);
$booking->price = $request->price;
$booking->profile = 'pending';
Method 2 : Here checking schedules_id equal to exists schedules_id then update seat and other data's
Problem : Insert new data updating old data
Method 2 code :
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id], // match the row based on this array
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => json_encode($seat),
'price' => $request->price,
'profile' => 'pending',
]
);
// I don't know this is logically correct or wrong
My idea : Here I'm retrieving old data and storing into one variable then merging old data and new data into one column
Problem : Getting error.
My idea code :
$extSeat = DB::table('bookings')->select('seat')->get();
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat)),
'price' => $request->price,
'profile' => 'pending',
]);
what i actually need ? : i need merge exists data with new data without updating.
Old data look like A1,B1
when insert new data like C1
i need data like this A1,B1,C1
I hope I explain clear enough. Any help is appreciated, thank you.
I don't know this is a correct logic or not but works for me, any other suggestions are welcome.
$extSeat = DB::table('bookings')->select('seat')->first();
$extSeat = explode(",", $extSeat->seat);
$booking = Bookings::updateOrCreate(
['schedules_id' => $schedules_id],
[ // update this columns
'buses_id' => $buses_id,
'routes_id' => $routes_id,
'seat' => implode(",", array_merge($seat,$extSeat )),
'price' => $request->price,
'profile' => 'pending',
]);
Laravel provides a great help for developers to save all input fields of a form which is one record with one line of code.
like if I want to save a form which has multiple input fields and one record to database like:
then I can save it with below code and it works great:
SaveOrder:: create($request->all());
Now I have a question. If I have multiple records (multiple rows) in a form and I can add new rows with a button pressed. Then how can I save all records with above code?
Like:
It's easy to do that using Eloquent :
$data = array(
array('field1'=>'value1', 'field2'=> value2),
array('field1'=>'value1', 'field2'=> value1),
//...
);
Model::insert($data);
Assuming your input names look something like name[], since you can add rows on the fly, you can retrieve the input as an array, and insert them using something like this:
$data = [];
$names = request('name');
$product_names = request('product_name');
$product_colour = request('product_colour');
$product_size = request('product_size');
for ($i = 0; $i < count($names); $i++) {
// Add checks to make sure indices actually exist, probably using preprocessing in JS
$data[] = [
'name' => $names[$i],
'product_name' => $product_names[$i],
'product_colour' => $product_colour[$i],
'product_size' => $product_size[$i],
];
}
Model::insert($data);
The best answer for this question is using foreach statement. Like:
$CustomerName= $request -> input('CustomerName');
$ProductId= $request -> input('ProductId');
$ProductName= $request -> input('ProductName');
$ProductColor= $request -> input('ProductColor');
foreach( $ProductId as $key => $n ) {
SaveOrder::insert(
array(
'CustomerName' => $CustomerName[$key],
'ProductId' => $ProductId[$key],
'ProductName' => $ProductPrice[$key],
'ProductColor' => $ProductQuantity[$key],
)
);}
Use upsert
If you use Laravel 8 or above, you can make use of upsert. Such an useful function to insert or update matching records at the same time.
SaveOrder::upsert($request->all(), ['id'], ['CustomerName', 'ProductName', 'ProductColor', 'ProductID']);
The method's first argument consists of the values to insert or update, while the second argument lists the column(s) that uniquely identify records within the associated table. The method's third and final argument is an array of the columns that should be updated if a matching record already exists in the database. The upsert method will automatically set the created_at and updated_at timestamps if timestamps are enabled on the model:
Flight::upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
Read the documentation on Laravel Upsert
I am inserting multiple rows at the same time, say 2 rows
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
How can I get those inserted ids.
I am doing it, this way for now.
foreach($multiple_rows as $row){
DB::table('users')->insert($row);
$record_ids[] = DB::getPdo()->lastInsertId();
}
Any other good way to do it, without inserting single row each time.
You could do something like the following:
$latestUser = DB::table('users')->select('id')->orderBy('id', 'DESC')->first();
$multiple_rows = [
['email' => 'taylor#example.com', 'votes' => 0],
['email' => 'dayle#example.com', 'votes' => 0]
];
DB::table('users')->insert($multiple_rows);
$users = DB::table('users')->select('id')->where('id', '>', $latestUser->id)->get();
If you really need all the inserted ID's
$dataArray = [
['name' => 'ABC'],
['name' => 'DEF']
];
$ids = [];
foreach($dataArray as $data)
{
$ids[] = DB::table('posts')->insertGetId($data);
}
To get all id with a massive insertion I think the good way is to first get the last id in the table, make the massive insertion and get the last id. In theory they must follow, unless there has been an insertion from another connection. To avoid that the solution is a transaction.
Update
Also read the documentation
I use the sync function for syncing a belongsToMany Relation:
$model->products()->sync($productIds);
In the $productIds array there is flat array with some Id's -
something like this:
$productIds = [1,3,5,6];
What I want:
The pivot table has also additional columns like "created_by" and "updated_by".
But how can I add these fields to my array WITHOUT doing a foreach loop?
Is there a shorter way to do this?
I need an array like this:
$productIds = [1 => [
'created_by' => 1,
'updated_by' => 1
],3 => [
'created_by' => 1,
'updated_by' => 1
],5 => [
'created_by' => 1,
'updated_by' => 1
],6 => [
'created_by' => 1,
'updated_by' => 1
]];
Yes I know I can do it with foreach and add the columns while I loop through the array. But I want do it shorter.. is there a way to do it shorter (perhaps with laravel)?
It should be enough to pass what you have set in $productIds in your code example to sync().
This method works not only with array of integers. You can also pass an array where key is the synced ID and value is the array of pivot attributes that should be set for given ID.
This should do the trick:
$productIds = [
1 => [
'created_by' => 1,
'updated_by' => 1
]
//rest of array
];
$model->products()->sync($productIds);
Just make sure you have defined those fields as pivot fields in your relation definition.
In order to generate such table based on a list of IDs in $productIds you can do the following:
$productIds = array_fill_keys($productIds, array(
'created_by' => 1,
'updated_by' => 1,
));