Laravel 10中通过hasManyThrough获取带子级图片的所有父级分类数据
解决方法
1. 修正模型关联错误
你的PhotoCategories模型中photos方法的hasManyThrough参数顺序有误,正确的参数顺序规则是:
return $this->hasManyThrough( 最终关联模型类, 中间关联模型类, 中间表关联主表的外键, 最终表关联中间表的外键, 主表主键, 中间表主键 );
修正后的photos方法代码:
class PhotoCategories extends Model { public function photo_detail() { return $this->hasMany(PhotoDetail::class); } public function photos() : HasManyThrough { return $this->hasManyThrough( Photo::class, PhotoDetail::class, 'photo_categories_id', // 中间表PhotoDetail关联主表的外键 'photo_detail_id', // 最终表Photo关联中间表的外键 'id', // 主表PhotoCategories的主键 'id' // 中间表PhotoDetail的主键 ); } }
2. Controller层实现
在对应控制器(例如PhotoCategoryController)中编写方法,获取所有分类并预加载关联图片,避免N+1查询问题:
namespace App\Http\Controllers; use App\Models\PhotoCategories; class PhotoCategoryController extends Controller { public function index() { // 获取所有分类,预加载每个分类下的第一张图片 $categories = PhotoCategories::with(['photos' => function($query) { $query->take(1); }])->get(); return view('photo-categories.index', compact('categories')); } }
3. Blade模板渲染
在视图文件(例如resources/views/photo-categories/index.blade.php)中,循环渲染分类名称和对应图片:
<div class="category-list"> @foreach($categories as $category) <div class="category-item"> <h2>{{ $category->name }}</h2> @if($category->photos->isNotEmpty()) <img src="{{ asset('storage/' . $category->photos->first()->image) }}" alt="{{ $category->name }} 示例图片"> @else <p>该分类暂无图片</p> @endif </div> @endforeach </div>
注意:如果图片存储在
public/storage目录下,需先执行php artisan storage:link创建软链接,确保图片可正常访问;若图片存在其他路径,调整asset()内的路径即可。
可选优化
如果需要获取分类下最新的一张图片,可在预加载闭包中添加排序规则:
$categories = PhotoCategories::with(['photos' => function($query) { $query->latest()->take(1); }])->get();
内容的提问来源于stack exchange,提问作者anofeb
相关产品推荐
相关产品推荐

