在 for-each 循环之外保存模型

Save model outside of for-each loop

假设模型顺序

class Order extends Model {
    use HasFactory;

    protected $table = 'order';

    protected $primaryKey   = 'id';
    public $incrementing = false;
    protected $keyType = 'string';
    protected $guarded = [];

    public function extra(){
        return $this->hasOne(Extra::class);
    }

    public function products(){
        return $this->hasMany(Product::class);
    }
}

额外模型

class Extra extends Model {

    use HasFactory;
    protected $table = 'extra';
    protected $guarded = [];

    public function order(){
        $this->belongsTo(Order::class);
    }
}

型号产品

class Product extends Model {
    use HasFactory;
    protected $table = 'product';
    protected $guarded = [];
    public function order(){
        return $this->belongsTo(Order::class);
    }
}

现在,我从 API 接收数据。有了这些数据,我想提供模型,然后将信息存储到数据库中。

atm取款方式是:

foreach ($list as $item) {
    $order = new Order();
    $order->id = $item['id'];
    $order->title = $item['title'];
    $order->save();

    $extra = new Extra();
    $extra->foo= $item['path']['to']['foo'];
    $extra->bar= $item['path']['to']['bar'];
    $order->extra()->save($extra)
    
    $order->products()->createMany($item['path']['to']['products']);
}

问题是这段代码每次循环保存三次,一次订单,一次额外,一次产品。 我想知道我是否可以使用另一种方法来收集 for-each 内部和外部的数据,以制作类似

的内容
Order::insert($array_of_data);

我想它看起来像这样,试一试,如果不起作用请告诉我,我会删除答案

$orders = [];
$extras = [];
$products = [];

foreach ($list as $item) {
   
    $orders[] = [
        'id' => $item['id'],
        'title' => $item['title'],
    ];

    $extras[] = [
        'foo' => $item['path']['to']['foo'],
        'bar' => $item['path']['to']['bar'],
    ];

    $products[] = [
       'order_id' => $item['id'],
       'foo' => $item['path']['to']['products']['foo'] // or data it has
    ];
}

Order::insert($orders);
Extra::insert($extras);
Product::insert($products); // make sure each product has order id and data which is not visible here

我还建议研究将 $list 转换为集合,然后对其进行迭代,如果数据很大,您可以使用 LazyCollection,它与集合相同,但更适合处理更大的数据集

这是一个使用延迟收集的示例

LazyCollection::make($list)
    ->each(function (array $item) {
        $order = Order::create(
            [
                'id' => $item['id'], 
                'title' => $item['title']
            ],
        );
                
        Extra::create(
            [
                'order_id' => $item['id'], 
                'foo' => $item['path']['to']['foo'],
                'bar' => $item['path']['to']['bar'],
            ],
        );
                
        $order->products()->createMany($item['path']['to']['products']);
    });

虽然它不一定一次创建很多,但它可以节省内存并且处理速度非常快