laravel DB::transaction how to update records? - laravel

I have a function in a controller like this:
DB::transaction(function () use ($request) {
for ($parts=0; $parts < count($request->name) ; $parts++) {
$parts_info = new PartsInfo;
$parts_info -> part_id = $request -> id;
$parts_info -> name = $request -> name[$parts];
$parts_info -> qty = $request -> qty[$parts];
$parts_info -> price = $request -> price[$parts];
$parts_info -> save();
}
});
Now I want to update the records. How do I do that? Here multiple records have the same part_id which has a one-to-many relationship with another table.
Note: Tried using $parts_info = PartsInfo::where('parts_id', $request->id)->get(); and without get()

Try this one
DB::transaction(function () use ($request) {
for ($parts=0; $parts < count($request->parts) ; $parts++) {
PartsInfo::where("parts_id", $request->id)->update([
"name" => $request->name[$parts],
"qty" => $request->qty[$parts],
"price" => $request->price[$parts]
]);
}
});

try this one
DB::transaction(function () use ($request) {
for ($parts=0; $parts < count($request->parts) ; $parts++) {
PartsInfo::where('id', $request->id[$parts])->update([
"name" => $request->name[$parts],
"qty" => $request->qty[$parts],
"price" => $request->price[$parts]
]);
}
});
You will have to check it with the id and because you are checking it with parts_id so it will not work
or You can first delete the child records and then recreate it
DB::transaction(function () use ($request) {
$count = $request->parts;
PartsInfo::where('parts_id', $request->id)->delete();
for ($parts=0; $parts < $count ; $parts++) {
PartsInfo::create([
'parts_id' => $request->id,
"name" => $request->name[$parts],
"qty" => $request->qty[$parts],
"price" => $request->price[$parts]
]);
}
});

Related

select column from an array based on id

I want to filter through this array $bank_totals and select a value of amount only.
$bank_totals = $bank_totals->bank_balances();
"id" => 1
"bank" => "KCB"
"amount" => 7622.0
]
1 => array:3 [
"id" => 2
"bank" => "I & M Bank"
"amount" => 25000.0
am getting the id from user input $data['id']; I want when the $data['id'] = 2 example the value shown is 25000
$data = request()->all();
$bank_totals = $bank_totals->bank_balances();
(to appear here)
here is my bank_balances method
class TransactionsRepository
{
public function bank_balances(){
$banks_data = Bank::all();
$banks_totals = [];
foreach ($banks_data as $bank){
$totals = (BankingTransactions::where('bank_id', $bank->id)->sum('amount')) -
((PettyCash::where('bank_id', $bank->id)->sum('amount')) + ((PayDoctor::where('bank_id', $bank->id)
->sum('total_paid'))));
array_push($banks_totals,
[
'id'=>$bank->id,
'bank'=>$bank->name,
'amount'=>$totals,
]);
}
return $banks_totals;
}
}
Replace your bank_balances method with this:
public function bank_balances($id = null) {
$banks_data = Bank::all();
$banks_totals = [];
if (is_null($id)) {
foreach ($banks_data as $bank) {
$totals = (BankingTransactions::where('bank_id', $bank->id)->sum('amount')) -
((PettyCash::where('bank_id', $bank->id)->sum('amount')) + ((PayDoctor::where('bank_id', $bank->id)
->sum('total_paid'))));
array_push(
$banks_totals,
[
'id' => $bank->id,
'bank' => $bank->name,
'amount' => $totals,
]
);
}
return $banks_totals;
} else {
return (BankingTransactions::where('bank_id', $id)->sum('amount')) -
((PettyCash::where('bank_id', $id)->sum('amount')) + ((PayDoctor::where('bank_id', $id)
->sum('total_paid'))));
}
}
And use it like this:
$bank_totals = $bank_totals->bank_balances($data['id']);

Laravel - How to update table multiple rows at once

I have this variable called $projectFieldOptions and it's output is like this:
https://prnt.sc/7HtxrfTy9HiI.
Now, In the Controller I need to update this. What I am doing this, first delete all the existing rows based on id_feed and id_project and then loop through this variable $projectFieldOptions and insert it. Like this:
if( $request->feed_type !== 'scrape' ) {
$delete_mapping = DB::connection($db_name)->table($db_name . '.feed_mappings')
->where('id_feed', '=', $id_feed)
->where('id_project', '=', $token)
->delete();
}
// now insert
$field_mapping = true;
if( $request->feed_type !== 'scrape' ) {
if( count($projectFieldOptions) ) {
foreach ($projectFieldOptions as $mapping) {
$data[] = [
'id_feed' => $id_feed,
'id_project' => $token,
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['custom'] ? $mapping['custom_field'] : $mapping['text'],
'custom_field' => $mapping['custom'],
'updates' => $mapping['updates'],
'removes' => $mapping['removes'],
'import' => 1,
'date_add' => now(),
'date_upd' => now()
];
}
} else {
$data = [];
}
$field_mapping = DB::connection($db_name)->table($db_name . ".feed_mappings")->insert($data);
}
Now, I don't want to delete existing rows instead I want to update those rows based on the id_feed_mappings. Can you tell how can I do this?
Check if this would work, to update based on id_feed_mappings value, you can use the ->where('id_feed_mappings', '=' ,'a value or variable') before ->update($data)
if( $request->feed_type !== 'scrape' ) {
// try using update instead of insert
$field_mapping = true;
if( $request->feed_type !== 'scrape' ) {
if( count($projectFieldOptions) ) {
foreach ($projectFieldOptions as $mapping) {
$data[] = [
'id_feed' => $id_feed,
'id_project' => $token,
'import_field_slug' => $mapping['value'],
'internal_field_slug' => $mapping['custom'] ? $mapping['custom_field'] : $mapping['text'],
'custom_field' => $mapping['custom'],
'updates' => $mapping['updates'],
'removes' => $mapping['removes'],
'import' => 1,
'date_add' => now(),
'date_upd' => now()
];
}
} else {
$data = [];
}
$field_mapping = DB::connection($db_name)->table($db_name . ".feed_mappings")->update($data);
}

The Laravel way of separating items in a collection based on user_id

In the Event-model I have this relationship:
public function eventQuestionUsers(){
return $this->hasMany( 'App\EventQuestionUsers' );
}
So when I get an $event in my Controller, I do this:
public function show( $event_id ){
$user = Auth::user();
$event = Event::where( [ 'id', '=', $event_id ] )->get();
if( $user->can( 'manage', $event ) ){
$event->load( 'eventQuestionUsers' );
}
return view( single_event, [
'event' => $event
]);
}
But now I'm I would like the collection to split-up the eventQuestionUsers based on the user_id. So that it would look like this:
$event = [
'name' => 'Blah blah',
'date' => '2021-09-18 20:30:00'
'eventQuestionUsers' => [
15 => [ // 15 is a user_id
$eventQuestionUser,
$eventQuestionUser,
],
16 => [ // 16 is a user_id
$eventQuestionUser,
$eventQuestionUser,
$eventQuestionUser,
$eventQuestionUser,
],
18 => [ // 18 is a user_id
$eventQuestionUser,
$eventQuestionUser,
],
]
Solution attempt
Normally I would just make a public static helper-function, that takes $eventQuestionUsers and an input and returns what I want, by iterating over the whole this, like such:
public static function clusterEventQuestionUsersBasedOnUserId( $eventQuestionUsers ){
$returned = [];
foreach( $eventQuestionUsers as $eventQuestionUser ){
$user_id = $eventQuestionUser->user_id;
if( ! array_key_exists( $user_id, $returned ) ){
$returned[ $user_id ] = [];
}
$returned[ $user_id ][] = $eventQuestionUser;
}
return $returned;
}
I wouldn't use a Collection, since that is immutable, so adding entries like seen above usually is a bit of a pain.
What is 'The Laravel Way' of doing this? Or does it sound fine? It feels very 'un-laravel' like.
By default, $event->eventQuestionUsers is a collection instance and this means you can use laravel collection methods directly on it and in this case, groupBy(). So
public function show( $event_id ){
$user = Auth::user();
$event = Event::where( [ 'id', '=', $event_id ] )->get();
if( $user->can( 'manage', $event ) ){
$event->load( 'eventQuestionUsers' );
$event->eventQuestionUsers->groupBy('user_id');//the only new stuff
}
return view( single_event, [
'event' => $event
]);
}
Im unsure if i understood you correctly, but if you have the user_id in your relation, you can group by your lazy eager load like so
$event->load(['eventQuestionUsers' => function($query) {
$query->groupBy('user_id');
}]);
Laravel Docs

Incremental number on factory, Laravel

I have a factory that is called several times, but on contract_year column I get the same value.
$factory->define(ContractYear::class, function (Faker $faker) {
$contract = Contract::orderByDesc('id')->first();
$contract_year = ContractYear::select('contract_year')->orderByDesc('id')->value('contract_year');
if($contract_year == null){
$contract_year = 2019;
}
return [
'contract_id' => $contract->id,
'contract_year' => $contract_year++,
'licensed_users' => $faker->randomDigit,
];
});
I call it from here..
$u->contracts()->saveMany(factory(Contract::class, rand(1, 5))->create()->each(function ($contract){
$contract->years()->saveMany(factory(ContractYear::class, $contract->number_of_years)->create());
}));
You can use static
$factory->define(ContractYear::class, function (Faker $faker) {
static $contract_year;
$contract = Contract::orderByDesc('id')->first();
if(!$contract_year) {
$contract_year = ContractYear::select('contract_year')->orderByDesc('id')->value('contract_year') ?? 2019;
}
return [
'contract_id' => $contract->id,
'contract_year' => $contract_year++,
'licensed_users' => $faker->randomDigit,
];
});
Reference: `static` keyword inside function?
Attach a counter to $this
$factory->define(ContractYear::class, function (Faker $faker) {
$this->sequences = $this->sequences ?? [];
$contract = Contract::orderByDesc('id')->first();
$group = $contract->id ?? 0;
$this->sequences[$group] = $this->sequences[$group] ?? 2019;
return [
'contract_id' => $contract->id,
'contract_year' => $this->sequences[$group]++,
'licensed_users' => $faker->randomDigit,
];
});
Might be worth looking into Laravel 8 new Model factories for more explicit object oriented approach

Laravel - Unique Request Rules allows duplicate

In Laravel-5.8 I applied Rules Request for multiple fields as shown below:
public function rules()
{
return [
'goal_type_id' => [
'required',
Rule::unique('appraisal_goals')->where(function ($query) {
return $query
->where('employee_id', 1)
->where('appraisal_identity_id', 1);
})
],
'appraisal_doc' => 'nullable|mimes:doc,docx,xls,xlsx,ppt,pptx,pdf,jpg,jpeg,bmp,png,|max:5000',
'weighted_score' => 'required|numeric|min:0|max:500',
];
}
This is mysql query:
ALTER TABLE appraisal_goals
ADD CONSTRAINT appraisal_goals_uniq1 UNIQUE KEY(goal_type_id,appraisal_identity_id,employee_id);
This is meant for create. From the code the combination of goal_type_id, employee_id and appraisal_identity_id are unique.
When I click on submit in create blade, it allows duplicate.
How do I resolve this?
Also, how do I write the one for update?
Please note that my route is appraisal_goal
Thank you
Try this code for update
public function rules()
{
$appraisal_goal_id = 'take your appraisal_goals id here from request';
return [
'goal_type_id' => [
'required',
Rule::unique('appraisal_goals')->ignore($appraisal_goal_id, 'id')->where(function ($query) {
return $query
->where('employee_id', 1)
->where('appraisal_identity_id', 1);
})
],
'appraisal_doc' => 'nullable|mimes:doc,docx,xls,xlsx,ppt,pptx,pdf,jpg,jpeg,bmp,png,|max:5000',
'weighted_score' => 'required|numeric|min:0|max:500',
];
}

Resources