获取每个产品的第一张图片
Get first image for each product
我尝试获取最新的 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
它在 product
和 image
之间有一个 morph
关系
产品型号
class Product extends Model {
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
图片模型
class Image extends Model {
public function imageable()
{
return $this->morphTo();
}
}
当使用 with 作为键值数组时,闭包的 $el
参数将是一个尚未执行的查询构建器。
限制结果查询生成器的方法是使用take()
。因此你的代码应该是这样的。
->with(['images', function($el) {
$el->take(1);
}])
编辑 要使此解决方案有效,您需要额外的 package. Using the following trait should make it work and using limit instead. See the following .
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')
.
添加图像
以上解决方案都很好。我个人更喜欢我认为会很理想的不同解决方案。
我要为产品定义不同的关系:
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 那里学到了这个和其他有用的数据库技巧
public function images()
{
return $this->hasMany(Image::class);
}
public function firstImage()
{
return $this->images()->first();
}
只需创建一个函数来定义产品与其图像之间的关系。
然后创建一个获取第一张图片的函数
我尝试获取最新的 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
它在 product
和 image
morph
关系
产品型号
class Product extends Model {
public function images()
{
return $this->morphMany(Image::class, 'imageable');
}
}
图片模型
class Image extends Model {
public function imageable()
{
return $this->morphTo();
}
}
当使用 with 作为键值数组时,闭包的 $el
参数将是一个尚未执行的查询构建器。
限制结果查询生成器的方法是使用take()
。因此你的代码应该是这样的。
->with(['images', function($el) {
$el->take(1);
}])
编辑 要使此解决方案有效,您需要额外的 package. Using the following trait should make it work and using limit instead. See the following
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')
.
以上解决方案都很好。我个人更喜欢我认为会很理想的不同解决方案。
我要为产品定义不同的关系:
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 那里学到了这个和其他有用的数据库技巧public function images()
{
return $this->hasMany(Image::class);
}
public function firstImage()
{
return $this->images()->first();
}
只需创建一个函数来定义产品与其图像之间的关系。 然后创建一个获取第一张图片的函数