Laravel 5.2 multiple model save()
Asked Answered
V

4

9

I need to store exactly three pages at once via form. I would like save in similar manner as model save() method, because this will automatically update record timestamps.

How to do this for multiple records at once?

My page Model:

namespace App;
use Illuminate\Database\Eloquent\Model;

class Page extends Model{
     protected $table = 'simple_pages';
}

My code:

public function createPages(Request $request){ // I use Page at the top
     $data = [
          [
          'title'=> $request->first,
          'content'=> $request->firstCont
          ],[
          'title'=> $request->second,
          'content'=> $request->secondCont
          ][
          'title'=> $request->third,
          'content'=> $request->thirdCont
          ]
     ];
     Page::unguard();
     $pages = new Page($data);
     $pages->save(); // Something like this would be amazing
     Page::reguard();
}

Note: I am strongly against creating multiple instances of Page model, and then Loop them to save them each individualy. Also, I dont want to use DB insert, because it will not update record timestamps automaticaly.

Vaudeville answered 5/4, 2016 at 19:8 Comment(1)
I know this is an old question but the solution is Page::insert($data). See this answer: https://mcmap.net/q/117781/-how-to-insert-multiple-rows-from-a-single-query-using-eloquent-fluentConcinnous
V
5

After long long search looks like I found this:

        $eloquentCollection->each(function ($item, $key) {
            $item->save();
        });

Yes, it is Iteration, but looks like there are no other methods how to save multiple models. The only alternative is to use DB::insert(), but be aware of not having automaticaly updated timestamps.

Also, if you are willing to have too much eloquent models to save, save them by chunks because of possible memory issues (or push them into Queue).

Vaudeville answered 12/4, 2016 at 13:31 Comment(1)
In newer Laravel-Versions (since version 5.4) you can shorten this to: $eloquentCollection->each->save();Augustusaugy
U
4

Here's the best solution I found to implement

User::create([array of multiple user detail arrays])

with avoid the need to executes as much queries as you have entries to add

Allow Eloquent to save multiple records at once

Unaccountable answered 21/3, 2017 at 11:59 Comment(0)
F
2

If you read the manual Mass Assignment.

public function createPages(Request $request){ // I use Page at the top
     $data = [
          [
          'title'=> $request->first,
          'content'=> $request->firstCont
          ],[
          'title'=> $request->second,
          'content'=> $request->secondCont
          ][
          'title'=> $request->third,
          'content'=> $request->thirdCont
          ]
     ];

     Page::unguard();
     $pages = Page::create($data);
     Page::reguard();
}
Friedcake answered 5/4, 2016 at 19:14 Comment(4)
Thanks for answer. I already read official docs, but it provided no help to me. Page::create($data) creates exception(preg_match() expects parameter 2 to be string, array given); I also tried Page::create([ ... first ....],[ ... second ....],[ ... third ....]), but it just inserts single blank record to database, which is not what I want to achieve.Vaudeville
But if your columns are not listed inside of protected $fillable = [] it wont work. If you have set $fillable and your arrays are set, you need to make sure your values are actually strings and not arrays. i.e. $request->first and $request->firstContFriedcake
I used model unguard() and reguard() model methods. Therefore the guarded/fillable should not be an issue here (or is it? - If it would be an Issue, Laravel would throw mass assignment exception). I am 100% sure, about content of my requests. I recently checked with dd(). All of them are strings.Vaudeville
@Vaudeville true Unguard would make $fillable irrelevant, missed that. Looking at create it goes through the __construct to fill Maybe you can debug that a bit?Friedcake
M
0
$data = [
      [
      'title'=> $request->first,
      'content'=> $request->firstCont
      ],[
      'title'=> $request->second,
      'content'=> $request->secondCont
      ][
      'title'=> $request->third,
      'content'=> $request->thirdCont
      ]
 ];

foreach($data as $page) {
      Page::create($page);
    }

should solve your issue

Mackinnon answered 13/8, 2018 at 11:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.