How to increment column with Laravel Eloquent updateOrCreate()? - laravel

Is it possible to return the model id from the request below ?
Bar::insert([
'foo_id' => Foo::updateOrCreate([
'code' => $row[0],
'name' => $row[1]
])->increment('count')->id
]);
I also tried this:
Foo::updateOrCreate([
'code' => $row[0],
'name' => $row[1]
], [
'count' => DB::raw('count + 1')
])->id
But it doesn't work at inserting because it count is not yet set.
HINT: There is a column named "count" in table "foos", but it cannot be referenced from this part of the query. (SQL: insert into "public"."foos" ("id", "name", "count") values (123, Hello, count+1) returning "id")
=== EDIT ===
With DB::raw('IFNULL(count,0) + 1'), I'm getting:
SQLSTATE[42703]: Undefined column: 7 ERROR: column "count" does not exist
LINE 1: ... ("code", "name", "count") values ($1, $2, IFNULL(count,0) +...
^
HINT: There is a column named "count" in table "foos", but it cannot be referenced from this part of the query. (SQL: insert into "public"."foos" ("code", "name", "count") values (123, Hello, IFNULL(count,0) + 1) returning "id")

Unfortunately I don't think this is possible to reference the count column only when the update happens (since this is what is happening here). You will need to take the roundabout way:
$model = Foo::firstOrNew([
'code' => $row[0],
'name' => $row[1]
]);
$model->count = ($model->exists ? $model->count : 0) + 1;
$model->save();
Here $model->exists will be true if the model was retrieved from the database or false if a new one was created.
Efficiency-wise firstOrCreate is what updateOrCreate does anyway so there's no query cost added

try using IFNULL
Foo::updateOrCreate([
'code' => $row[0],
'name' => $row[1]
], [
'count' => DB::raw('IFNULL(count,0) + 1')
])
if you want the id, try it like this:
$id=(Foo::updateOrCreate([
'code' => $row[0],
'name' => $row[1]
], [
'count' => DB::raw('IFNULL(count,0) + 1')
]))->id;
note: this is working on mysql, not PostgreSQL

you just need to set column auto-increment in database and not need set it column in your eloquent

Related

Laravel | three fields combination Valdiation

How to do a 3 fields combination validation?
I have this table merchant_product, the table has 4 columns :
id
merchant_id
product_id
branch_id
I don't want the same row duplicated like this when storing data.
Example :
id
merhcant_id
product_id
branch_id
1
1
1
1
2
1
1
1
I tried this approach but it seems not to work.
Here is my sample validation method :
$rules = [
'product_id' => ['required','unique:merchant_product,product_id,NULL,id,merchant_id,'.Auth::id()', new Varchar],
'merchant_id' => [new Varchar],
'branch_id' => ['required','unique:merchant_product,branch_id,NULL,id,merchant_id,'.Auth::id()', new Varchar],
];
You can use Rule::unique to validate both column together :
'product_id' => [
'required',
Rule::unique('merchant_product')->where(function ($query) use($request) {
return $query->where('product_id', $request->product_id)
->where('branch_id', $request->branch_id);
}),
],
Don't forget to add use Illuminate\Validation\Rule; on the top
Use firstOrCreate()
MerchantProduct::firstOrCreate([
'product_id' => $productId,
'merchant_id' => $merchantId,
'branch_id' => $brandId
]);
This will stop any duplicate record being created, using all 3 columns without doing extra processing with rules.
See the following article for usage:
https://laravel.com/docs/8.x/eloquent#retrieving-or-creating-models

How can i get last inserted row By using Laravel DB::table()->insert()?

I user this code for insert data .
$conv = DB::table('conversations')
->insert([
'is_seen' => $other_user_id,
'user_one' => $user_id,
'user_two' => $other_user_id,
'user_one_status' => 1,
'user_two_status' => 0,
'message_status' => 0,
'last_message' => $messageCon
]);
Its return true false value. I need last inserted row.
Assuming there's a reason you're not using Eloquent, you could use insertGetId.
$conv = DB::table('conversations')
->insertGetId([
'is_seen' => $other_user_id,
'user_one' => $user_id,
'user_two' => $other_user_id,
'user_one_status' => 1,
'user_two_status' => 0,
'message_status' => 0,
'last_message' => $messageCon
]);
Caveats from the documentation:
Auto-Incrementing IDs
If the table has an auto-incrementing id, use the insertGetId method to insert a record and then retrieve the ID:
When using PostgreSQL the insertGetId method expects the auto-incrementing column to be named id. If you would like to retrieve the ID from a different "sequence", you may pass the column name as the second parameter to the insertGetId method.
Insert cant return whole row.
You can change it to insertGetId and then select it from database by that id.
Or use models, and use create method (Conversation::create([...]))

Update a 1 Row 1 Column with Multiple Values

i've some problem with my code.
$id = DB::table('sn_project_details')->insertGetId([
'emp_name' => $request->emp_name,
'emp_id' => $request->emp_id,
'department' => $request->department,
'submit_date' => $request->submit_date,
'total_amount' => $request->total_amount,
'project_tittle' => $request->project_tittle,
'project_desc' => $request->project_desc,
'scope' => $request->scope,
'file' => $request->file
]);
//Update Table
\DB::table('sn_project_details')
->where('project_id', $id)
->update(['doc_ref' => "ID_",$request->scope,"_",$id]);
return redirect('/user')
I want to update column doc_ref with example value ID_Scope_220,
ID_ its fixed value. Scope from textbox scope. 220 from #emp_id.
but when i execute this code, update query not working properly.
can someone help? thx
use dot instead of comma
->update(['doc_ref' => "ID_".$request->scope."_".$emp_id]);

How do I get a value of another table on Laravel?

I'm trying to get just value of id column on a table but it returns
SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '[{"id":1}]' for column 'id_jenis' at row 1 (SQL: insert into `pesanan` (`name`, `telpon`, `alamat`, `id_jenis`, `jenis`, `do`, `updated_at`, `created_at`) values (Pradita Candrani, 0813, Jalan Sunan Ampel Kasin, [{"id":1}], Cuci Basah Standar, None, 2019-11-27 12:18:35, 2019-11-27 12:18:35))
Here it is my code on Controller
public function pesan(Request $request){
$harga = Harga::select('id')->where('nama',$request->jenis)->get();
Pesanan::create([
'name' => $request->nama,
'telpon' => $request->telpon,
'alamat' => $request->alamat,
'id_jenis' => $harga,
'jenis' => $request->jenis,
'do'=>$request->do
]);
return redirect('/pesanan');
}
how can I fix this? Please help
You're getting object now and passing it to id_jenis directly. use first() instead of get(). and pass the $harga->id in id_jenis.
$harga = Harga::select('id')->where('nama',$request->jenis)->first();
Pesanan::create([
'name' => $request->nama,
'telpon' => $request->telpon,
'alamat' => $request->alamat,
'id_jenis' => $harga->id,
'jenis' => $request->jenis,
'do'=>$request->do
]);
If you want to store multiple ids in id_jenis then use pluck.
$harga = Harga::where('nama',$request->jenis)->pluck('id')->toArray();
Here you'll get multiple ids in array. so use json_encode to store JSON in db as below.
Pesanan::create([
'name' => $request->nama,
'telpon' => $request->telpon,
'alamat' => $request->alamat,
'id_jenis' => json_encode($harga),
'jenis' => $request->jenis,
'do'=>$request->do
]);
$harga = Harga::select('id')->where('nama',$request->jenis)->get();
After this line, write
\Log::info(['Harga', $harga]);
and check the latest file and error in /storage/logs/laravel.log
Welcome to the wonderful world of debugging

Will Model::updateOrCreate() update a soft-deleted model if the criteria matches?

Let's say I have a model that was soft-deleted and have the following scenario:
// EXISTING soft-deleted Model's properties
$model = [
'id' => 50,
'app_id' => 132435,
'name' => 'Joe Original',
'deleted_at' => '2015-01-01 00:00:00'
];
// Some new properties
$properties = [
'app_id' => 132435,
'name' => 'Joe Updated',
];
Model::updateOrCreate(
['app_id' => $properties['app_id']],
$properties
);
Is Joe Original now Joe Updated?
OR is there a deleted record and a new Joe Updated record?
$variable = YourModel::withTrashed()->updateOrCreate(
['whereAttributes' => $attributes1, 'anotherWhereAttributes' => $attributes2],
[
'createAttributes' => $attributes1,
'createAttributes' => $attributes2,
'createAttributes' => $attributes3,
'deleted_at' => null,
]
);
create a new OR update an exsiting that was soft deleted AND reset the softDelete to NULL
updateOrCreate will look for model with deleted_at equal to NULL so it won't find a soft-deleted model. However, because it won't find it will try to create a new one resulting in duplicates, which is probably not what you need.
BTW, you have an error in your code. Model::updateOrCreate takes array as first argument.
RoleUser::onlyTrashed()->updateOrCreate(
[
'role_id' => $roleId,
'user_id' => $user->id
],
[
'deleted_at' => NULL,
'updated_at' => new \DateTime()
])->restore();
Like this you create a new OR update an exsiting that was soft deleted AND reset the softDelete to NULL
Model::withTrashed()->updateOrCreate([
'foo' => $foo,
'bar' => $bar
], [
'baz' => $baz,
'deleted_at' => NULL
]);
Works as expected (Laravel 5.7) - updates an existing record and "undeletes" it.
I tested the solution by #mathieu-dierckxwith Laravel 5.3 and MySql
If the model to update has no changes (i.e. you are trying to update with the same old values) the updateOrCreate method returns null and the restore() gives a Illegal offset type in isset or empty
I got it working by adding withTrashed so that it will include soft-deleted items when it tries to update or create. Make sure deleted_at is in the fillable array of your model.
$model = UserRole::withTrashed()->updateOrCreate([
'creator_id' => $creator->id,
'user_id' => $user->id,
'role_id' => $role->id,
],[
'deleted_at' => NULL
])->fresh();
try this logic..
foreach ($harga as $key => $value) {
$flight = salesprice::updateOrCreate(
['customerID' => $value['customerID'],'productID' => $value['productID'], 'productCode' => $value['productCode']],
['price' => $value['price']]
);
}
it work for me

Resources