Laravel 将请求解析为带有关系的 Eloquent 模型

Gle*_*son 3 php api json laravel laravel-5

我正在开发一个 Laravel API,它将托管和管理移动应用程序的数据。我正在编写的应用程序将发出 AJAX 请求并将 JSON 数据发送到 Laravel 控制器。

这对于基本模型来说效果很好,但是我无法让它适用于嵌套模型。不好解释一下:

所以我有以下模型结构:

货架----有很多---->盒子----有很多---->产品

架子:

class Shelf extends Model
{
    protected $fillable = ['name', 'location'];

    public function boxes()
    {
        return $this->hasMany('App\Box');
    }
}
Run Code Online (Sandbox Code Playgroud)

盒子:

class Box extends Model
{
    protected $fillable = ['name', 'size', 'label'];

    public function shelf()
    {
        return $this->belongsTo('App\Shelf');
    }

    public function products()
    {
        return $this->hasMany('App\Product');
    }
}
Run Code Online (Sandbox Code Playgroud)

产品:

class Product extends Model
{
    protected $fillable = ['name', 'price', 'quantity'];

    public function box()
    {
        return $this->belongsTo('App\Box');
    }
}
Run Code Online (Sandbox Code Playgroud)

我的所有模型在保存任何内容之前都会进行验证检查。

我将以下请求发送到我的 Laravel 控制器:

{
  "name":"Shelf 1",
  "location":"LOC1"
  "boxes":[{
    "name":"box 1",
    "size": 130,
    "label": "B1",
    "products":[
      {"name":"Prod1","price":23.00,"quantity":5},
      {"name":"Prod2","price":13.00,"quantity":2}
    ]
  }, {
    "name":"box 2",
    "size": 130,
    "label": "B2",
    "products":[
      {"name":"Prod3","price":3.00,"quantity":15},
      {"name":"Prod4","price":7.00,"quantity":8}
    ]
  }, {
    "name":"box 3",
    "size": 160,
    "label": "B3",
    "products":[
      {"name":"Prod5","price":103.00,"quantity":9},
      {"name":"Prod6","price":83.00,"quantity":1}
    ]
  }]
}
Run Code Online (Sandbox Code Playgroud)

当我在 Laravel 控制器中收到上述数据时,我使用:

$shelf = new Shelf;
$shelf->fill($request->all());
$shelf->save();
Run Code Online (Sandbox Code Playgroud)

然而,要获取所有数据,这只会保存货架,而不会保存任何关系。有没有一种通用的方法(或库)可以用来解析 Laravel 控制器中的 JSON?

Sty*_*hon 5

据我所知,Eloquent 并没有提供类似的东西。您需要单独保存每一项。我可以建议这样的事情:

$shelf = Shelf::create($request->only(['name', 'location']));
foreach ( $request->input('boxes') as $box )
{
    $box = new Box($box);
    $shelf->boxes()->save($box);
    $pTemp = [];
    foreach ( $box['products'] as $product )
    {
        $pTemp[] = new Product($product);
    }
    $box->products()->saveMany($pTemp);
}
Run Code Online (Sandbox Code Playgroud)

更新

为了最大限度地减少运行的查询数量,我们可以循环遍历所有框一次,创建它们,然后再次循环遍历它们以创建所有产品。您仍然需要为每个盒子运行一个查询来创建产品,但据我所知,没有办法解决这个问题。

$shelf = Shelf::create($request->only(['name', 'location']));
$bTemp = [];
foreach ( $request->input('boxes') as $i => $box )
{
    $bTemp[$i] = new Box($box);
}
$shelf->boxes()->saveMany($bTemp);
foreach ( $request->input('boxes') as $i => $box )
{
    $pTemp = [];
    foreach ( $box['products'] as $product )
    {
        $pTemp[] = new Product($product);
    }
    $bTemp[$i]->products()->saveMany($pTemp);
}
Run Code Online (Sandbox Code Playgroud)