Laravel Eloquent insert 3 rows at once with timestamp
Solution 1
insert()
is a part of Query Builder, so it doesn't use Eloquent features.
You can't pass 3 items to create()
method, only one. And using create()
inside loops is terrible idea.
You should add these fields manually when doing bulk insertion:
[
'application_id' => $applications[0]->a_id,
'group_id' => $group->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
],
Solution 2
You may use dateTime
class :
[
'application_id' => $applications[0]->a_id,
'group_id' => $group->id,
'created_at' => new \dateTime,
'updated_at' => new \dateTime,
],
Comments
-
Benyi almost 2 years
I'm making a site with Laravel 5.2
I would like to do is
INSERT
3 rows at the same time- The new 3 rows have to contain timestamp
created_at
updated_at
.
With the
Query Builder
methodinsert
, Yes, it does insert 3 rows at once by passing an array like:GroupRelation::insert([ [ 'application_id' => $applications[0]->a_id, 'group_id' => $group->id, ], [ 'application_id' => $applications[1]->a_id, 'group_id' => $group->id, ], [ 'application_id' => $applications[2]->a_id, 'group_id' => $group->id, ], ]);
The code above works fine. But this cannot touch the timestamp. Which means the
created_at
updated_at
will be null.However, if I changed the method
insert
tocreate
:GroupRelation::create([ ... ]);
It received the error:
ErrorException in Model.php line 2983: preg_match() expects parameter 2 to be string, array given
If I'm not wrong, it seems like
create
can just accept 1 row at the same time, right?I know
insert
is not a part ofEloquent
.Eloquent
fires timestamps butQuery Builder
does not.So my questions are:
insert
method can accept 3 rows at one time, but how can I fire the timestamp manually?- By
1.
I've tried to add'created_at' => date('Y-m-d H:i:s'),
at each items of the array. But the controller is unclear and horrible. - How can I pass an array of 3 items to
create
method in order to fire timestamps? - Is it a good idea to call
create
inside the loops?
PS.
protected $guarded = []
was assigned to empty array so would not receive Mass Assignment Exception.Thank you so much.
-
Benyi over 7 yearsThanks! Yes, I've done that! But I have 3 rows. As you see, I have 3 items of the array. Each of them is almost same and a little difference of
$applications
index among them. If I manually addcreated_at
updated_at
to the array set, the code is triplicate. Any further ideas? -
Kyslik over 7 yearsI am sure there is already question like that, why instead of searching for duplicate you choose to answer? I am just curious...
-
Alexey Mezenin over 7 years@Benyi you can create an array and then just iterate over it and add timestamps to each item. It's the best solution you've got.
-
Alexey Mezenin over 7 years@Kyslik usually people who post links to 'duplicates', post links to not really related questions. I hate that and prefer to answer questions with related code and explanation. If you found helpful similar question, please post the link.
-
Benyi over 7 yearsThanks @AlexeyMezenin and @Kyslik! This is a good idea for me. Hope AlexeyMezenin's answer and suggestion are helpful to that people who are confusing with timestamp not fired, and
create
no bulk insertion. Thank you so much. -
Benyi over 7 years@AlexeyMezenin By your suggestion provided yesterday, I've used
array_walk()
walking through each of the item, and create new sub-items (created_at
,group_id
...) of that item in the closure. Finally I got the finished array with no triplicate same code. That is what I want. :) -
Alexey Mezenin over 7 yearsGlad it was helpful. )
-
Benyi over 7 yearsThank you for answering. In this question, the way to get current time is not relevant. It's about timestamp not updating by
insert()
method. And it can't insert more than 1 row bycreate
method which is able to update timestamp.