You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel如何缓存带完整关联的Eloquent模型并还原为对应实例

解决方案

核心问题原因

  • hydrate() 是批量处理数据集的方法,返回的始终是Eloquent集合,即使传入单个模型的属性数组也会返回包含1个元素的集合,直接调用模型属性会报错。
  • 直接通过toJson()序列化后的关联数据是普通数组,默认的模型填充逻辑不会自动将其还原为关联模型实例。

方案一:直接缓存序列化模型(推荐,99%场景适用)

Laravel的Eloquent模型本身实现了序列化接口,缓存系统会自动处理序列化/反序列化逻辑,完整保留所有属性和预加载的关联关系,不需要额外处理:

if (Cache::has($website->id.'_main_page')) {
    $page = Cache::get($website->id.'_main_page');
} else {
    $expiresAt = now()->addMinutes(60);
    $page = Page::with(['sections', 'pageSections.sectionObjects'])
        ->where('website_id', $website->id)
        ->where('main', 1)
        ->first();
    Cache::put($website->id.'_main_page', $page, $expiresAt);
}

该方案取出的$page就是完整的Page模型实例,所有关联关系都是对应的模型对象,修改器、访问器、追加属性等逻辑都可以正常运行。

方案二:JSON存储场景手动还原

如果必须用JSON格式存储缓存(比如跨系统共享缓存),可以手动还原主模型和关联:

if (Cache::has($website->id.'_main_page')) {
    $data = json_decode(Cache::get($website->id.'_main_page'), true);
    // 还原主模型,第二个参数true表示该实例已存在于数据库
    $page = (new Page())->newInstance($data, true);
    
    // 还原一级关联sections
    $page->setRelation('sections', Section::hydrate($data['sections']));
    
    // 还原多层关联pageSections.sectionObjects
    $pageSections = PageSection::hydrate($data['page_sections']);
    $pageSections->each(function (PageSection $section) use ($data) {
        $objects = collect($data['page_sections'])
            ->where('id', $section->id)
            ->first()['section_objects'] ?? [];
        $section->setRelation('sectionObjects', SectionObject::hydrate($objects));
    });
    $page->setRelation('pageSections', $pageSections);
} else {
    $expiresAt = now()->addMinutes(60);
    $page = Page::with(['sections', 'pageSections.sectionObjects'])
        ->where('website_id', $website->id)
        ->where('main', 1)
        ->first();
    Cache::put($website->id.'_main_page', $page->toJson(), $expiresAt);
}

注意事项

  • 关联名对应的JSON键名是蛇形命名,比如pageSections序列化后会变成page_sections,需要对应上
  • 嵌套关联需要逐层调用setRelation方法绑定

缓存使用建议

  • 页面/关联数据更新时,主动删除对应缓存键,避免返回脏数据
  • 如果缓存数据量级不大,优先使用方案一,开发成本和性能都优于JSON还原方案

内容的提问来源于stack exchange,提问作者Matrix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:27:05