如果不存在,Laravel将获得大小数量0

Sve*_*art 13 php laravel eloquent

我想列出所有可用产品和每个尺寸的数量

 name     | size1  | size2  | size 3 | size4   | total
 ________________________________________________________
 t-shirt1 |   0    |    1   |    3    |   9    | 13
 t-shirt2 |   3    |    1   |    1    |   9    | 14
 t-shirt3 |   0    |    0   |    0    |   0    | 0
Run Code Online (Sandbox Code Playgroud)

我的Product模型与之ProductSize类似:

public function sizeAvailable(){
    return $this->hasMany('App\ProductSize');

}
Run Code Online (Sandbox Code Playgroud)

ProductSize与之有关系Product:

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

productSize与之有关系Size:

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

ProductSize模型包含金额值.所以我能够获得适当数量的产品的所有尺寸,并且我也能够从一个尺寸获得所有产品.如何在我的示例中创建列表.是否可以使用大小作为索引?所以我可以做(伪代码)来填充<td>标签:

for(all products)
{
    if(product[somesize] not null)
      {{ product[somesize]->amount }}
    else
       0
}
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是,<tr>如果有例如1个大小(size3),我不知道如何设置表中的数量,而当我这样做时没有其他数据$product->sizeAvailable()只包含1个值(size3),所以我需要将0放在size1下但是如何检查size1是否不适用于该产品?或者有更好的方法来填充表格大小金额?

我目前拥有的:

 <table id="myTable" class="tablesorter table table-striped table-responsive">
        <thead>
        <tr>
            <th>
                Product
            </th>
            @foreach($sizes as $size)
                <th>
                    {{ $size->name }}
                </th>
            @endforeach
        </tr>
        </thead>
        <tbody>

            @foreach($products as $product)
                <tr >
                    <td>
                        {{ucfirst($product->name)}}
                    </td>
                    @foreach($sizes as $size)
                        <td>
                             HERE I NEED TO DO A CHECK IF $product HAS $size RETURN 0 ELSE RETURN ProductSize->amount
                        </td>
                    @endforeach



                </tr>
            @endforeach

        </tbody>
    </table>
Run Code Online (Sandbox Code Playgroud)

我可以在产品模型中创建一个函数,如:

 hasSize($size)
 {
    $result = select from ProductSize where size = $size  

    if ($result = null)
       return 0;

    return $result->amount();
 }
Run Code Online (Sandbox Code Playgroud)

但是使用这个解决方案,我必须运行一个查询products * sizes时间,如果我有1000个产品和20个大小,那么一个表只能获得20.000个查询.

____________________________
Relevant Database data
____________________________


products
-id           (primary key)
-name

sizes
-id           (primary key)
-name

product_sizes
-pr           (primary key)
-prodcut_id
-size_id
-amount
Run Code Online (Sandbox Code Playgroud)

luc*_*aos 7

您已手动构建了多对多关系,Laravel已为其提供了一些有用的功能:

1.更新产品型号(添加或替换现有关系):

public function sizes()
{
    // many to many relation with intermediate table column
    return $this->belongsToMany('App\Size', 'product_sizes')->withPivot('amount');
}

public function getTotalAttribute()
{
    // access pivot table directly and use sum aggregate
    return DB::table('product_sizes')->where('product_id', $this->attributes['id'])->sum('amount');
}
Run Code Online (Sandbox Code Playgroud)

2.检索模型(在控制器中),如下所示:

$sizes = Size::all();
$products = Product::with('sizes')->get(); // eager load sizes
Run Code Online (Sandbox Code Playgroud)

3.刀片模板:

...
<td>
    {{ucfirst($product->name)}}
</td>
@foreach($sizes as $size)
<td>
    {{-- HERE I NEED TO DO A CHECK IF $product HAS $size RETURN 0 ELSE RETURN ProductSize->amount --}}
    {{-- check and retrieve by using Collection methods --}}
    {{ $product->sizes->contains($size) ? $product->sizes->find($size)->pivot->amount : 0 }}
</td>
@endforeach
<td>{{ $product->total }}</td>
....
Run Code Online (Sandbox Code Playgroud)

在使用上面的更改和一个(非常小的)数据库种子重新创建示例后,我得到:

Product     size1   size2   size3   total
T-shirt1    10      3       0       13
T-shirt2    5       0       0       5
Run Code Online (Sandbox Code Playgroud)
  • 默认情况下,此解决方案由于急切加载而仅生成3个查询.(使用DebugBar验证)每个total计算都添加一个查询(遗憾的是,Laravel查询构建器没有透视表的聚合方法).

  • contains()find()在视图中遍历预取的集合 - 此处没有其他查询.

  • 您不需要该ProductSize模型,因为它只包含一个带有附加属性(amount)的数据透视表.查看多对多关系并检索中间表列.

  • 为方便起见:如果将product_sizes表重命名为product_size并遵循Laravel的表命名约定,$this->belongsToMany('App\Size', 'product_sizes')则不需要第二个参数,可以这样写:$this->belongsToMany('App\Size')

[product_size]表是从相关模型名称的字母顺序派生而来的.