首页 > 解决方案 > 如何在 Laravel 7 中不使用关系查询多对多

问题描述

背景资料:

我正在建立一个资产跟踪系统。我有一个Product有很多Stock。现在,库存可以是容器或容器内的组件。请看下面的例子。


例子

容器和组件示例

在这张图片中,您可以看到两个产品

  1. L-Acoustics LA8(有 40 个库存)[每个库存都是容器内的一个组件]
  2. L-Acoustics LA-RAK II(有 4 个库存)[每个库存都是一个容器]

我的目标:

我希望能够显示我上次更新时拥有的所有容器。就像下面的图片

我想要的是

问题:

我无法显示上次更新容器的时间。由于我访问关系的方式,不允许我进入枢轴并获取最后更新。

我试过的:

我与Stock模型本身创建了多对多关系,并将数据透视表称为“component_container”。

这是与我的问题相关的数据库关系:

数据库设计

这是我的股票模型:

// Stock.php

class Stock extends Model {
    protected $guarded = [];

    protected $casts = [
        'product_id' => 'integer',
        'quantity'   => 'integer'
    ];

    public function getContainerAttribute()
    {
        return $this->container()->first();
    }

    public function getComponentsAttribute()
    {
        return $this->components()->get()->flatten()->all();
    }

    public function product()
    {
        return $this->belongsTo(Product::class);
    }

    public function container()
    {
        return $this->belongsToMany(Stock::class, 'component_container', 'component_id', 'container_id')->withTimestamps();
    }

    public function components()
    {
        return $this->belongsToMany(Stock::class, 'component_container', 'container_id', 'component_id')->withTimestamps();
    }
}       

这是用于显示我的容器的控制器:

// ContainerController.php

class ContainerController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function index()
    {
        $containers = Stock::has('components')->paginate(20);
        return view('containers.index', compact('containers'));
    }
}

这是容器/index.blade.php

// index.blade.php

<div class="table-responsive">
    <table class="table table-borderless table-striped table-vcenter">
        <thead>
            <tr>
                <th>Barcode</th>
                <th>Name</th>
                <th class="d-none d-sm-table-cell">Updated</th>
            </tr>
        </thead>
        <tbody>
            @forelse($containers as $container)
                <tr>
                    <td>
                        <a href="{{route('products.stocks.show', [$container->product->slug, $container->barcode])}}">
                            <strong>{{ $container->barcode }}</strong>
                        </a>
                    </td>
                    <td>
                        {{ $container->product->name }}
                    </td>
                    <td class="d-none d-sm-table-cell">

                    </td>
                </tr>
            @empty
                <tr>
                    <td colspan="100" class="text-center">Nothing Available</td>
                </tr>
            @endforelse
        </tbody>
    </table>
</div>

标签: phplaraveleloquent

解决方案


推荐阅读