Laravel Eloquent模型如何按collection_type获取对应表最新10条数据?
在Laravel Eloquent中实现动态获取对应表的最新10条记录
你的需求完全可以实现,但当前写法存在几个关键问题,导致无法正常工作:
$with数组仅支持返回Relation实例的Eloquent关联方法,而你的most_recent直接返回查询结果集合,不符合配置要求;- 模型未从数据库加载数据时,
$this->collection_type为null,调用Relation::getMorphedModel会直接报错; - 批量查询
collections时,每条记录都会触发一次单独查询,引发N+1性能问题。
正确实现方案
步骤1:配置模型映射
先在App\Providers\AppServiceProvider的boot方法中配置morph映射,让collection_type的字符串值对应到实际模型类:
use Illuminate\Database\Eloquent\Relations\Relation; use App\Models\Post; use App\Models\Page; use App\Models\Testimonial; public function boot() { Relation::morphMap([ 'post' => Post::class, 'page' => Page::class, 'testimonial' => Testimonial::class, ]); }
步骤2:用访问器实现动态获取
在Collection模型中定义访问器,同时处理批量查询的N+1问题:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\Relation; class Collection extends Model { protected $table = 'collections'; // 定义访问器,自动获取对应表的最新10条记录 public function getMostRecentAttribute() { if (is_null($this->collection_type)) { return collect(); } $modelClass = Relation::getMorphedModel($this->collection_type); // 校验模型类是否存在,避免报错 if (!class_exists($modelClass)) { return collect(); } return $modelClass::latest('id')->take(10)->get(); } // 自定义批量预加载方法,避免N+1查询 public static function withMostRecent() { return static::get()->each(function ($collection) { $collection->setAttribute('most_recent', $collection->getMostRecentAttribute()); }); } }
使用方式
- 查询单个记录:
$collection = Collection::find(1); $latestItems = $collection->most_recent; // 直接访问属性即可
- 批量查询(规避N+1):
$collections = Collection::withMostRecent(); foreach ($collections as $collection) { // 直接使用$collection->most_recent }
补充说明
如果你的业务场景中collection和对应表的记录存在关联(比如collections有related_id字段),可以改用多态关联实现,但根据需求描述,只是根据collection_type获取对应表的最新10条,访问器的方式更直接高效。
内容的提问来源于stack exchange,提问作者jon
相关产品推荐
相关产品推荐

