如何在 eloquent 关系中显示具有至少一个属性的属性族?
How to show attribute family having at least one attribute in eloquent relationship?
我有三个模型:
- 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);
}
}
- 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');
}
}
- 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
我的结果是这样的:
不显示产品不使用的那些属性族。如果您有更好的想法,请提出建议。
我有三个模型:
- 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);
}
}
- 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');
}
}
- 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
我的结果是这样的:
不显示产品不使用的那些属性族。如果您有更好的想法,请提出建议。