Why my updateOrInsert doesn't work in laravel 9x - php

I use updateOrInsert to avoid duplicate data, why doesn't the Update function work and always insert data?
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;
use App\Models\Wip;
use App\Models\db2;
class WipController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function index(Request $request)
{
$tgl_skrg = date('Y-m-d 00:00:00');
$tgl_skrg2 = date('Y-m-d 23:00:00');
$nilai = '00017';
$db2s = DB::connection('mysql2')->table("wip_tracking_1")->get();
$data = json_decode($db2s, true);
foreach ($data as $db2 ){
DB::table('wip_tracking')
->updateOrInsert(
[
"TP" =>$db2 ['TP'],
"TP_code"=>$db2 ['TP_code'],
"VIN"=>$db2 ['VIN'] ,
"Flag"=>$db2 ['Flag'] ,
"Suffix"=>$db2 ['Suffix'] ,
"Color_Code"=>$db2 ['Color_Code'] ,
"Scan_date"=>$db2 ['Scan_date'] ,
"Production_date"=>$db2 ['Production_date'] ,
"Production_shift"=>$db2 ['Production_shift'] ,
"Model_code"=>$db2 ['Model_code'] ,
"Brand"=>$db2 ['Brand'] ,
"Destination_code"=>$db2 ['Destination_code'] ,
"WIP_code"=>$db2 ['WIP_code'] ,
"ADM_Production_ID"=>$db2 ['ADM_Production_ID'] ,
"Plan_delivery_date"=>$db2 ['Plan_delivery_date'] ,
"created_at" => date('Y-m-d H:i:s'),
],
[
"ADM_Production_ID"=> $db2['ADM_Production_ID']
],
[
"VIN"=> $db2['VIN']
],
);
}
}

updateOrInsert should receive two parameter arrays. The first one is a conditional array, which will check for the records and second array of columns and values to be updated or inserted.
e.g.
DB::table('users')
->updateOrInsert(
['email' => 'john#example.com', 'name' => 'John'],
['votes' => '2']
);
first array ['email' => 'john#example.com', 'name' => 'John'] will look for matching column => value pairs.
second array ['votes' => '2'] will update or insert data based on findings.
https://laravel.com/docs/9.x/queries#update-or-insert
In your case, it seems that you're trying to match a lot of values in your first array, which might be the reason why exact match is never found and it's always producing a new entry, try to limit and keep your conditional array more spcific.

Related

How to insert an array of values into a particular column and fetch it

So, I want to insert an entire array of values into a particular column and I don't know exactly what to do. Everything I have tried gives me the "Array to string conversion" error.
Here is my controller code:
public function processInternationaTransfer(Request $request)
{
$international_info = Validator::make($request->all(),
[
'beneficiary_name' => 'required',
'beneficiary_acc_num' => 'required|numeric',
'beneficiary_bank' => 'required',
'beneficiary_swiftcode' => 'required',
'routing_transit_no' => 'required|numeric',
'currency' => 'required',
'amount' => 'required|numeric',
'note' => 'required',
]
);
if($international_info->fails())
{
return response()->json(['errors'=>$international_info->errors()->all()]);
}
$info = $international_info->validated();
$balance = $info['currency'].'_balance';
if(user_details()->$balance < InternationalAmount($info['amount']))
{
return response()->json(['insufficient_amount'=>'Insufficient Amount']);
}
else
{
TransactionLog::create([
'username' => user()->username,
'type' => 'Exchange',
'cred_deb' => 'Debit',
'time'=> Carbon::now('Africa/Lagos')->format('l, d F, Y g:i A'),
'status' => 2,
'amount'=>InternationalAmount($info['amount']),
'currency'=>$info['currency'],
'reason' => $info['note'],
'inter_details' => $info,
'transaction_id' => rand(100000000, 999999999),
]);
return response()->json(['success'=>'Transaction Processed, Awaiting Confirmation']);
}
}
How do I insert that array of values into the inter_details column?
I tried inserting it as it is above, and it gives me "array to string conversion" error.
I want to be able to fetch it after inserting it.
First of all you need to make sure that the inter_details can accept many characters the best way to do that is to use the json() in migrations
$table->json('inter_details'); //it will create a longText column in database so that it can accept many characters.
then add a casts to the TransactionLogs Model
protected $casts = [
'inter_details' => 'array',
]
in this way you can access the inter_details as an array when you fetch it from the database you don't need to use json_encode() and json_decode(). if you want to casts it in other types there are many more from the documentation
Eloquent: Mutators & Casting - Attribute Casting
To insert an array of values into a particular column, you need to use the DB facade's insert method. The insert method takes an array of values as its first argument and the table name as its second argument.
For example, if you want to insert an array of values into the inter_details column, you can do the following:
$inter_details = [
'beneficiary_name' => 'John Doe',
'beneficiary_acc_num' => '12345678',
'beneficiary_bank' => 'Bank of America',
'beneficiary_swiftcode' => 'ABC123',
'routing_transit_no' => '123456789',
'currency' => 'USD',
'amount' => '1000',
'note' => 'This is a test transaction',
];
DB::table('transaction_logs')->insert([
'inter_details' => json_encode($inter_details),
]);
The json_encode() function is used to convert the array into a JSON string, which can then be stored in the database.
To fetch the array of values from the database, you can use the DB facade's select method. For example:
$inter_details = DB::table('transaction_logs')->select('inter_details')->get();
$inter_details = json_decode($inter_details, true);
The json_decode() function is used to convert the JSON string back into an array. The second argument of the function is set to true, which tells the function to return an associative array instead of an object.
Now you have the array of values stored in the $inter_details variable, which you can use as you wish.

How to insert multiple rows in laravel, need explanation

I want to insert multiple rows in a table, where the data collection I am inserting has a unique number. For example : I am inserting 2 row for a user_id number 1. My codes from controller is : I want to keep DB::table() instead of laravel eloquent
foreach($post_data['user_id'] as $key => $no){
$set_base = DB::table('package_user')
->Insert([
'base_id' => $post_data['base_id'],
'base_title' => $post_data['base_title'],
'user_id' => $no,
'package_id' => $post_data['package_id'],
'plan_id' => $post_data['plan_id'],
'currency' => $post_data['currency'],
'payable_plan_amount' => $post_data['total_amount'],
'created_at' => Carbon::now()
]);
}
Please refer How to insert multiple rows from a single query using eloquent/fluent there is a solution for both eloquent and querybuilder
$data = [
['user_id'=>'Coder 1', 'subject_id'=> 4096],
['user_id'=>'Coder 2', 'subject_id'=> 2048],
];
Model::insert($data); // Eloquent approach
DB::table('table')->insert($data); // Query Builder approach
You can also use fill() method if the model instance already created with the pre-defined populated datas.
<code>
$modelObj = new Model();
$modelCollection = collect($request->input())->all();
$modelObj->fill($modelCollection);
$modelObj->save();
</code>

Creaty an single array by a Laravel Collection, but with specific fields

I have this Model where I'm calling with
$data = ProcessoSeletivoRDSincroniza::all();
This model gaves me a collection with more than 300 records, with attributes like name, celphone, email etc..
And I have to pass this collection to a API body request, by an array, this array has specific key fields, and the only way that I think about doing this its iterating this collection with a foreach loop, and creating/setting this array with this collection fields, and works ok, but my application does one request for every record, and this is not a good way to handle it.
So I'm thinking if's there a way to create an "custom" and single array with all that records, so I dont need to iterate and make a request by record, and just tranform all this records in a JSON file and send it.
This is my code now:
$data = ProcessoSeletivoRDSincroniza::all();
//$data = $data->toArray();
$api = new RDStationApi();
foreach($data as $row)
{
$events = array(
"event_type" => "CONVERSION",
"event_family" => "CDP",
"payload" => [
"conversion_identifier" => "Name of the conversion event",
"name" => $row->nome_completo,
"email" => $row->email,
"personal_phone" => $row->telefone,
"cf_ps_curso" => $row->ps_curso,
"cf_ps_ano_semestre" => $row->ps_anosemestre,
"cf_ps_data_vestibular_agendado" => $row->ps_data_vestibular_agendado,
"cf_ps_nota_enem" => (string) $row->ps_nota_enem,
"cf_forma_ingresso" => $row->ps_forma_ingresso,
"cf_ps_unidade" => $row->ps_unidade,
"cf_ps_situacao" => $row->ps_situacao
]
);
$return = $api->update_contact($events);
You can use a Laravel functionality called API-Resources.
https://laravel.com/docs/8.x/eloquent-resources
Create a new Resource for your Model:
php artisan make:resource ProcessoSeletivoRDSincronizaResource
Afterwards this will create a file in the Resource folder named; ProcessoSeletivoRDSincronizaResource , in this file you will need to adapt the toArray() method.
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ProcessoSeletivoRDSincronizaResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
//ADD ALL THE FIELDS, methods also work normally: $this->myMethod()
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
Afterwards you can use the Resource like this:
//for the whole collection
$events = ProcessoSeletivoRDSincronizaResource::collection(ProcessoSeletivoRDSincroniza::all());
//or for single use
$event = new ProcessoSeletivoRDSincronizaResource($single_model)

How to return last added id in Laravel

My controller code for adding data using laravel is given below. $request is globally declared
public function createEnquiry(Request $request){
//my table is enquirydetails
DB::table('enquirydetails')->insert(
['name' =>$request->input('name'),
'address' =>$request->input('address') ,
'phone' =>$request->input('phone') ,
'created_at' => date("Y-m-d H:i:s") ,
'updated_at' => date("Y-m-d H:i:s"),
]);
}
I need to return the id after it added to db. This code is a Lumen api db insertion code. Web path is
$router->group(['prefix' => 'Enquiry','namespace' => 'Enquiry'],
function($router){
$router->post('new','EnquiryController#createEnquiry');
});
Use insertGetId method to insert a record and then retrieve the ID:
$id = DB::table('tableName')->insertGetId(
['name' => $request->input('name'),
'address'=> $request->input('address')]
);
print_r($id);
for more details read Manual
First you should create a Model for your enquirydetails table. It could be like this:
EnquiryDetail.php - Model
And when doing the insertion, you can just easily do this
$detail = EnquiryDetail::create([
'name' =>$request->input('name'),
'address' =>$request->input('address') ,
'phone' =>$request->input('phone') ,
'created_at' => date("Y-m-d H:i:s") ,
'updated_at' => date("Y-m-d H:i:s"),
]);
If it's successful, you can already access the newly inserted id like this:
$detail->id
please assign Db:: to a variable example $result,
then print it
print_r($result);

Why is laravel's updateOrCreate creating new records instead of updating?

Code
Entry::updateOrCreate([
'intern_id'=>$intern['id'],
'created_at'=>Carbon::parse($input['date'])
],[
'company_id'=>$intern['supervisor']['company']['id'],
'content'=>$input['text']
]);
I'm using this code to try updating/creating a new record. It's suppose to matche intern_id and create_at column first. If found, then it creates a new one. However, it seems like it is always creating a new one and when it creates a new one, the company_id and intern_id column is set to 0 instead of the original value.
Note: intern_id or created_at are not PK columns.
Note2: created_at is a Date type, not DateTime
Use this code
Entry::updateOrCreate(['intern_id'=>$intern['id']],
[
'created_at'=>Carbon::parse($input['date']),
'company_id'=> $intern['supervisor']['company']['id'],
'content'=>$input['text']
]);
I believe this will work.
updateOrCreate() function of Model Abstract Class takes 2 parameters, but your parameter passing is breaking.
/**
* Create or update a record matching the attributes, and fill it with values.
*
* #param array $attributes
* #param array $values
* #return static
*/
public static function updateOrCreate(array $attributes, array $values = array())
{
$instance = static::firstOrNew($attributes);
$instance->fill($values)->save();
return $instance;
}
Entry::updateOrCreate(
[
'intern_id' => $intern['id'],
],
[
'created_at' => Carbon::parse($input['date'])
'company_id' => $intern['supervisor']['company']['id'],
'content' => $input['text']
]
);
because first argument array searched for first time
found one line with date and second line found other date deferent
-----------
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);
I had the same issue where it was only creating a record but it wasn't being updated in the event that the record exists.
The issue is that to allow for the mass assignment on the update you need to add the fields to be updated as fillable in your model.
In your Entry model you can have something close to this :
protected $fillable = [
'company_id',
'content',
];
I hope this helps in sorting out the issue.

Categories