If the entry exists, method updateOrCreate returns:
[2017-10-25 16:19:28] local.INFO: {"id":1,"name":"AC","code":"AC","updated_at":"2017-10-25 16:19:28","created_at":"2017-10-25 16:19:28"}
[2017-10-25 16:19:28] local.INFO: {"id":2,"name":"Acura","code":"ACURA","updated_at":"2017-10-25 16:19:28","created_at":"2017-10-25 16:19:28"}
[2017-10-25 16:19:29] local.INFO: {"id":3,"name":"Alfa Romeo","code":"ALFA_ROMEO","updated_at":"2017-10-25 16:19:29","created_at":"2017-10-25 16:19:29"}
If the entry NOT exists, method updateOrCreate returns:
[2017-10-25 16:19:28] local.INFO: {"id":0,"name":"AC","code":"AC","updated_at":"2017-10-25 16:19:28","created_at":"2017-10-25 16:19:28"}
[2017-10-25 16:19:28] local.INFO: {"id":0,"name":"Acura","code":"ACURA","updated_at":"2017-10-25 16:19:28","created_at":"2017-10-25 16:19:28"}
[2017-10-25 16:19:29] local.INFO: {"id":0,"name":"Alfa Romeo","code":"ALFA_ROMEO","updated_at":"2017-10-25 16:19:29","created_at":"2017-10-25 16:19:29"}
A id column is 0.
public function createMark($id, $name, $code) {
$item = CatalogMark::updateOrCreate([
'id' => (int)$id,
], [
'name' => (string)$name,
'code' => (string)$code,
]);
\Log::info($item);
return $item;
}
'id' => (int) $int,
What's $int? I'm surprised your code isn't throwing a PHP error on that line.
What's $int? I'm surprised your code isn't throwing a PHP error on that line.
Sorry, I incorrectly wrote the code for an example. Has corrected.
Now I looked at the way of the call:
CatalogModel::updateOrCreate >> \Illuminate\Database\Eloquent\Builder::updateOrCreate >>
return tap($this->firstOrNew($attributes), function ($instance) use ($values) {
$instance->fill($values)->save();
});
firstOrNew()?
I'm unable to reproduce.
Do the objects get inserted into your database?
Is the id column set to autoincrement?
I'm unable to reproduce.
Do the objects get inserted into your database?
Is the id column set to autoincrement?
Yes, records are created. There is no autoincrement in the table. I take a directory where the identifier is a unique number.
I have a table structure:
CREATE TABLE `catalog_marks` (
`id` int(11) NOT NULL,
`code` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL,
UNIQUE KEY `catalog_marks_id_unique` (`id`),
KEY `auto_ru_catalog_marks_code_index` (`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
And created entries:
id code name created_at updated_at
------ ---------- ---------- ------------------- ---------------------
1 AC AC 2017-10-25 16:47:29 2017-10-25 16:47:29
5 ACURA Acura 2017-10-25 16:47:29 2017-10-25 16:47:29
7 ALFA_ROMEO Alfa Romeo 2017-10-25 16:47:30 2017-10-25 16:47:30
And log...
[2017-10-25 16:47:29] local.INFO: {"id":0,"name":"AC","code":"AC","updated_at":"2017-10-25 16:47:29","created_at":"2017-10-25 16:47:29"}
[2017-10-25 16:47:29] local.INFO: {"id":0,"name":"Acura","code":"ACURA","updated_at":"2017-10-25 16:47:29","created_at":"2017-10-25 16:47:29"}
[2017-10-25 16:47:30] local.INFO: {"id":0,"name":"Alfa Romeo","code":"ALFA_ROMEO","updated_at":"2017-10-25 16:47:30","created_at":"2017-10-25 16:47:30"}
Still unable to reproduce. Attempting to add a record like this without an autoincrement id column causes a sql error (id doesn't have a default value).
Can you log the sql queries being executed by laravel?
Tell me how to do this? I call the method in the Artisan command.
In the id field, I pass a unique identifier. In the table, this field is PRIMARY. In this case, the autoincrement is not required.
I use a package to log all my sql queries https://github.com/mnabialek/laravel-sql-logger
Can you try using Tinker to do just the updateOrCreate call with your test data and see if the data is inserted correctly into the database?
I do not use tests. I load the data from the XML file by URL.
SQL:
/* Query 1 - 2017-10-25 17:39:16 [2.99ms] */
select * from `catalog_marks` where (`id` = '1') limit 1;
/*==================================================*/
/* Query 2 - 2017-10-25 17:39:16 [0.82ms] */
insert into `catalog_marks` (`id`, `name`, `code`, `updated_at`, `created_at`) values ('1', 'AC', 'AC', '2017-10-25 17:39:16', '2017-10-25 17:39:16');
/*==================================================*/
/* Query 3 - 2017-10-25 17:39:16 [0.89ms] */
select * from `catalog_marks` where (`id` = '5') limit 1;
/*==================================================*/
/* Query 4 - 2017-10-25 17:39:16 [0.66ms] */
insert into `catalog_marks` (`id`, `name`, `code`, `updated_at`, `created_at`) values ('5', 'Acura', 'ACURA', '2017-10-25 17:39:16', '2017-10-25 17:39:16');
/*==================================================*/
/* Query 5 - 2017-10-25 17:39:16 [0.9ms] */
select * from `catalog_marks` where (`id` = '7') limit 1;
/*==================================================*/
/* Query 6 - 2017-10-25 17:39:16 [0.79ms] */
insert into `catalog_marks` (`id`, `name`, `code`, `updated_at`, `created_at`) values ('7', 'Alfa Romeo', 'ALFA_ROMEO', '2017-10-25 17:39:16', '2017-10-25 17:39:16');
/*==================================================*/
/* Query 7 - 2017-10-25 17:39:16 [0.86ms] */
select * from `catalog_marks` where (`id` = '8') limit 1;
/*==================================================*/
/* Query 8 - 2017-10-25 17:39:16 [0.84ms] */
insert into `catalog_marks` (`id`, `name`, `code`, `updated_at`, `created_at`) values ('8', 'Alpina', 'ALPINA', '2017-10-25 17:39:16', '2017-10-25 17:39:16');
/*==================================================*/
Log::info():
[2017-10-25 17:39:16] local.INFO: {"id":0,"name":"AC","code":"AC","updated_at":"2017-10-25 17:39:16","created_at":"2017-10-25 17:39:16"}
[2017-10-25 17:39:16] local.INFO: {"id":0,"name":"Acura","code":"ACURA","updated_at":"2017-10-25 17:39:16","created_at":"2017-10-25 17:39:16"}
[2017-10-25 17:39:16] local.INFO: {"id":0,"name":"Alfa Romeo","code":"ALFA_ROMEO","updated_at":"2017-10-25 17:39:16","created_at":"2017-10-25 17:39:16"}
[2017-10-25 17:39:16] local.INFO: {"id":0,"name":"Alpina","code":"ALPINA","updated_at":"2017-10-25 17:39:16","created_at":"2017-10-25 17:39:16"}
A function:
private function createMark($id, $name, $code)
{
$item = CatalogMark::updateOrCreate([
'id' => (int)$id,
], [
'name' => (string)$name,
'code' => (string)$code,
]);
\Log::info($item);
return $item;
}
And table:
id code name created_at updated_at
------ ---------- ---------- ------------------- ---------------------
1 AC AC 2017-10-25 17:39:16 2017-10-25 17:39:16
5 ACURA Acura 2017-10-25 17:39:16 2017-10-25 17:39:16
7 ALFA_ROMEO Alfa Romeo 2017-10-25 17:39:16 2017-10-25 17:39:16
8 ALPINA Alpina 2017-10-25 17:39:16 2017-10-25 17:39:16
Right, I had forgotten to add 'id' to the $fillable property when trying to replicate. After doing that, everything works as expected.
Did you forget to add public $incrementing = false; to your model?
class CatalogMark extends Model
{
protected $fillable = ['id', 'code', 'name', 'dalion_cars_trade_mark_id'];
}
WOW! I added public $incrementing = false; to the model and the data began to be output without problems:
[2017-10-25 17:52:50] local.INFO: {"id":1,"name":"AC","code":"AC","updated_at":"2017-10-25 17:52:50","created_at":"2017-10-25 17:52:50"}
[2017-10-25 17:52:50] local.INFO: {"id":5,"name":"Acura","code":"ACURA","updated_at":"2017-10-25 17:52:50","created_at":"2017-10-25 17:52:50"}
[2017-10-25 17:52:50] local.INFO: {"id":7,"name":"Alfa Romeo","code":"ALFA_ROMEO","updated_at":"2017-10-25 17:52:50","created_at":"2017-10-25 17:52:50"}
Cool! Thanks!
My create method.....
public function create($request, $entity)
{
try{
DB::transaction(function() use($request, $entity){
$model_name = 'App\\'.$entity;
$model_instance = new $model_name;
$custs = $request->all();
$custid = $request->input('CUST_ID');//to get input cust_id
foreach ($custs as $cust)
{
$model_instance::updateOrCreate(['CUST_ID' => $custid] , $cust);
}
});
}catch(\Exception $e){
return response()->json(['error' => 'invalid'], 401);
}
return response()->json(['success' => 'success'], 200);
}
input::::::
[
{
"CUST_ID" : "001",
"SHOP_NAME" : "yyyyy",
"CONTACT" : "111111113",
"OWNER_NAME" : "agbh",
"VAT" : 15,
"ADDRESS" : "xys",
"REMARKS" : "good",
"OP_BALANCE" : 1000
}]
hai,
Can anyone tell why m not getting the CUST_ID inside the update or create method...
It does not check whether the data is already existing or not.
@Ankithalavanya, try this:
public function create($request, $entity)
{
try {
DB::transaction(function () use ($request, $entity) {
$model_name = 'App\\' . $entity;
/** @var \Illuminate\Database\Eloquent\Model $model_instance */
$model_instance = new $model_name;
$fillables = $model_instance->getFillable();
$custs = $request->only($fillables);
$CUST_ID = $request->input('CUST_ID');
$model_instance->query()
->updateOrCreate(compact('CUST_ID'), $custs);
});
} catch (Exception $e) {
return response()->json(['error' => 'invalid'], 401);
}
return response()->json(['success' => 'success']);
}
In general, accessing the model by passing the get parameter is a bad form.
For example, what happens if I specify example.com/api/foo123 in the URI?
In your case, I would do this:
public function create($request, $entity)
{
try {
$models = [
'foo' => App\Models\Foo::class,
'bar' => App\Models\Bar::class,
];
if (!array_key_exists($models, $entity)) {
return response()->json(['error' => 'invalid'], 401);
}
DB::transaction(function () use ($request, $entity, $models) {
/** @var \Illuminate\Database\Eloquent\Model $model */
$model = new $models[$entity];
$fillables = $model->getFillable();
$custs = $request->only($fillables);
$CUST_ID = $request->input('CUST_ID');
$model->query()
->updateOrCreate(compact('CUST_ID'), $custs);
});
} catch (Exception $e) {
return response()->json(['error' => 'invalid'], 401);
}
return response()->json(['success' => 'success']);
}
MY post request :localhost:8000/api/generic/test/new
AND I am trying to insert multiple "raw data"... It is not getting updated... it just creates a new row in the database...
thank you..
solved
Most helpful comment
WOW! I added
public $incrementing = false;to the model and the data began to be output without problems:Cool! Thanks!