如何正确使用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
相关产品推荐
相关产品推荐

