如何在 eloquent 关系中显示具有至少一个属性的属性族?

How to show attribute family having at least one attribute in eloquent relationship?

我有三个模型:

  1. product.php
class Product extends Model
{
    protected $table = 'products';

    // many to many relationship with product and attribute.
    public function attributes()
    {
        return $this->belongsToMany(Attribute::class);
    }

    
}
  1. Attributefamily.php

    {
            use HasFactory;
        
            protected $table = 'attributefamilies';
        
            protected $fillable = [
                'name',
                'order',
            ];
        
        
            public function scopeAsc($query)
            {
                return $query->orderBy('order', 'asc');
            }
        
        
            public function attributes()
            {
                return $this->hasMany(Attribute::class, 'attributefamilies_id');
            }
     }

  1. Attribute.php
class Attribute extends Model
    {
        protected $table = 'attributes';
    
        public function attribute_family()
        {
            return $this->belongsTo(Attributefamily::class, 'attributefamilies_id');
        }
    
        
        public function products()
        {
            return $this->belongsToMany(Product::class);
        }
    }

我的产品控制器显示产品如下所示:

class ProductController extends Controller
{
    public function show($slug)
    {
        $product = Product::with(['product_category', 'brand', 'attributes'])
        ->where('slug', $slug)->firstOrFail();

        $attribute_families = Attributefamily::with('attributes')->get();



        return view('frontend.product', compact(
            'product',
            'attribute_families'
        ));
    }
}

在我的product.blade.php

@if ($product->attributes->isNotEmpty())
    <div class="tab-pane fade show active':'' id="two" 
    role="tabpanel" aria-labelledby="two-tab">
        <div class="ipl-desc">
             <table>                               
                  @foreach ($attribute_families as $family)
                     <tr>
                        <td>{{ $family->name }}</td>
                        @foreach ($family->attributes as $attribute)
                            <td>{{ ($product->attributes->contains($attribute->id))?$attribute->name:'' 
                            }}</td>
                        @endforeach
                      </tr>
                     @endforeach
               </table>
        </div>
   </div>
@endif

我的产品页面如下所示:

最后,我想要的是只显示那些至少有一个这样的属性的属性族:

color red, green, blue.
size xl, m, sm.
//trim ram, processor, display, etc.

或者,我已经通过像这样更改查询来做到这一点:

class ProductController extends Controller
    {
        public function show($slug)
        {
            $product = Product::with(['product_category', 'brand', 'attributes' => function ($query) {
                $query->with('attribute_family');
            }])
            ->where('slug', $slug)->firstOrFail();
    

            return view('frontend.product', compact(
                'product',
            ));
        }
    }

最后无法处理更多。

我不确定我是否遵循了标准答案,但现在我是这样解决的: ProductController.php

        // for displaying product.
        $product = Product::with(['product_category', 'brand'])
            ->where('slug', $slug)
            ->first();

        // product with attribute family and attribute
        $products_with_afa = DB::table('products')
            ->join('attribute_product', 'products.id', '=', 
            'attribute_product.product_id')
            ->join('attributes', 'attributes.id', '=', 'attribute_product.attribute_id')
            ->join('attributefamilies', 'attributefamilies.id', '=', 
            'attributes.attributefamilies_id')
            ->select(
                DB::raw('GROUP_CONCAT(attributes.name) as attr_names'),
                DB::raw('GROUP_CONCAT(attributes.color_code) as attr_color_codes'),
                'attributefamilies.name as family_name'
            )
            ->groupBy('attributefamilies.name')
            ->where('products.slug', $slug)
            ->get();

在我的product.blade.php


@foreach ($products_with_afa as $product_with_afa)
<tr>
    <td>{{ $product_with_afa->family_name }}</td>
    
    @if ($product_with_afa->family_name == 'color')
        @foreach ( explode( ",", $product_with_afa->attr_color_codes ) as $attr_name)
            <td style="background-color:{!! $attr_name !!}"></td>
        @endforeach
    @else
        @foreach ( explode( ",", $product_with_afa->attr_names ) as $attr_name)
            <td>{{ $attr_name }}</td>
        @endforeach
    @endif
</tr>
@endforeach

我的结果是这样的:

不显示产品不使用的那些属性族。如果您有更好的想法,请提出建议。