我尝试获取最新的 10 产品及其图片,但只有第一张图片 所以这就是我尝试的
$newProducts = \App\Product::latest()->with(['images', function($el){
$el->first();
}])->with('category')->take(10)->get();
但是它给了我这个错误
mb_strpos() expects parameter 1 to be string, object given
它在morph
和product
之间具有image
关系
产品型号
class Product extends Model {
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
图像模型
class Image extends Model {
public function imageable()
{
return $this->morphTo();
}
}
答案 0 :(得分:2)
使用with作为键值数组时,闭包的$el
参数将是尚未执行的查询生成器。
限制结果的查询构建器的方法是使用take()
。因此,您的代码应如下所示。
->with(['images', function($el) {
$el->take(1);
}])
编辑,要使该解决方案有效,您将需要额外的package。使用以下特征应使其起作用,而应使用限制。请参阅以下post。
use \Staudenmeir\EloquentEagerLimit\HasEagerLimit;
->with(['images', function($el) {
$el->limit(1);
}])
Laravel解决方案是使用类似于属性的转换,您可以在以get开头和以attribute结尾的函数命名中创建自己的自定义属性。
class Product {
protected $appends = ['first_image'];
public function getFirstImageAttribute() {
return $this->images->first();
}
}
现在,如果您使用标准的Laravel
序列化,那么所有产品都将具有first_image字段,您可以在代码中像这样访问它。
$product->first_image;
为避免性能下降,请使用with('images')
添加图像。
答案 1 :(得分:2)
以上解决方案都很好。我个人更喜欢另一种我认为将是理想的解决方案。
我要为产品定义其他关系:
class Product extends Model {
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
public function firstImage()
{
return $this->morphOne(Image::class, 'imageable');
}
}
因此,您可以直接访问第一张图像或渴望加载关系:
$product->firstImage;
$product->load('firstImage');
Product::with('firstImage');
仅供参考,我在Laracon Online 2018中从Jonathan Reinink那里了解了这个以及其他有用的数据库技巧。
答案 2 :(得分:0)
public function images()
{
return $this->hasMany(Image::class);
}
public function firstImage()
{
return $this->images()->first();
}
只需创建一个定义产品及其图像之间关系的函数。 然后创建一个获取第一张图片的函数