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

如何正确使用Spatie\LaravelData获取并返回嵌套模型数据至前端?

解决Spatie LaravelData嵌套模型返回问题

针对你遇到的嵌套DTO返回问题,直接给你可行的实现方案:

1. 修改PostData类支持嵌套CategoryData

首先调整PostData,把关联的Category对应的CategoryData作为属性加入,同时确保能从模型自动转换:

class PostData extends Data
{
    public function __construct(
        public string $title,
        public string $category_id,
        public CategoryData $category,
    ) {
    }

    // 可选:手动实现从模型转换,也可以依赖LaravelData的自动映射
    public static function fromModel(Post $post): self
    {
        return new self(
            title: $post->title,
            category_id: $post->category_id,
            category: CategoryData::from($post->category),
        );
    }
}

2. 控制器中返回单个嵌套DTO(详情页)

在详情接口或页面中,必须预加载关联的Category(避免N+1查询),然后直接用PostData::from()转换模型:

public function show(Post $post)
{
    // 预加载关联模型
    $post->load('category');
    
    // 直接返回,Laravel会自动序列化为JSON给前端
    return PostData::from($post);
}

如果是返回给Blade视图,就把DTO传递到视图中:

public function show(Post $post)
{
    $post->load('category');
    $postData = PostData::from($post);
    
    return view('posts.detail', compact('postData'));
}

视图中直接访问嵌套属性:

<h1>{{ $postData->title }}</h1>
<p>分类:{{ $postData->category->category }}</p>
<p>分类描述:{{ $postData->category->description }}</p>

3. 控制器中返回嵌套DTO集合(列表页)

列表页同样需要预加载关联,然后用PostData::collection()转换整个模型集合:

public function index()
{
    // 预加载所有Post的Category关联
    $posts = Post::with('category')->get();
    
    // 转换为DTO集合并返回JSON
    return PostData::collection($posts);
}

常见报错排查

  • 如果出现Cannot instantiate CategoryData类的错误:大概率是没预加载category关联,导致$post->category为null,无法转换为CategoryData。确保查询时用with('category')或load('category')。
  • 如果字段类型不匹配:检查Data类的属性类型和模型字段类型是否一致,比如模型中category_id如果是整数,PostData里要改成public int $category_id。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 18:05:29