Laravel/Eloquent 规范化 JSON 响应的关系?
Posted
技术标签:
【中文标题】Laravel/Eloquent 规范化 JSON 响应的关系?【英文标题】:Laravel/Eloquent normalize relations for JSON response? 【发布时间】:2021-03-23 03:33:56 【问题描述】:(已编辑以添加一个更好的示例,其中包含同一本书和作者的多个角色)
使用 Laravel 8,但这一定是一个足够通用的问题,我只是不知道名称或找不到。我已经尝试过“规范化雄辩的 JSON 响应”,但似乎没有什么是这个特定的问题。
我在 Laravel 中定义了一些基本关系,但我想将它们分离出来以作为 JSON 响应。
例如
角色属于书本
图书属于作者
所以(忽略任何语法问题,它是快速键入的伪代码)
$characters = Character::with('book', 'book.author')->get();
$characters->toJson();
输出:
[
"id": 1,
"book_id": 1,
"name": "Some character",
"book": [
"id": 1,
"author_id": 1,
"name": "Some book",
"author": [
"id": 1,
"name": "Some author"
]
]
,
"id": 2,
"book_id": 1,
"name": "A second character",
"book": [
"id": 1,
"author_id": 1,
"name": "Some book",
"author": [
"id": 1,
"name": "Some author"
]
]
]
但我真正想要的是这样,我可以将它输入到前端 (React) 简单的 ORM 中,但没有嵌套和重复数据删除(例如,最初嵌套的响应可能具有多个字符的相同书籍条目)。
"characters": [
"id": 1,
"book_id": 1,
"name": "Some character"
,
"id": 2,
"book_id": 1,
"name": "A second character"
],
"books": [
"id": 1,
"author_id": 1,
"name": "Some book"
],
"authors": [
"id": 1,
"name": "Some author"
],
【问题讨论】:
如果您有多个Character
,那么您如何分隔这些书籍和作者?
我不确定你的意思?每个资源(字符、书籍、作者)都是其所有项目的数组,只要它们具有相关的外键 ID,我就可以查找它们
试试类似$characters = Character::with('book.author')->get(); $result = ["characters" => $characters->makeHidden('book'), "books" => $characters->books->makeHidden('author'), "authors" => $characters->books->$authors ]; return (json_encode($result));
或者试试这个:$characters = Character::get(); $books = Book::whereIn('id', $characters->pluck('book_id')->toArray())->get(); $authors = Author::whereIn('id', $books->pluck('author_id')->toArray())->get(); json_encode([ "characters" => $characters, "books" => , "authors" => $characters->books->$authors ])
【参考方案1】:
没有一个内置函数可以做所有事情;有时你只需要自己做。
因此,如果您想要单独的角色、书籍和作者,您只需要自己完成即可。当您急切加载关系时,Laravel 无论如何都会在后端分离查询,只需在您的代码中模拟这些查询。
// I assume this would be filtered in your live code,
// otherwise you're just returning every item in your database
$characters = Character::all();
$character_book_ids = $characters->pluck('book_id');
$books = Book::whereIn('id', $character_book_ids)->get();
$book_author_ids = $books->pluck('author_id');
$authors = Author::whereIn('id', $book_author_ids)->get();
return json_encode(compact('characters', 'books', 'authors'));
在此处查看代码示例:https://implode.io/XX948C
附带说明,您的数据库结构不完善。人物经常出现在不止一本书中,而且书中往往有不止一位作者。这些应该是与数据透视表的多对多关系。
【讨论】:
当然,这只是感觉它一定是一个非常普遍的问题,我并没有试图重新发明***。也就是说,你所拥有的就是我目前拥有的,但它丢失了我已经设置的所有关系,因为我基本上是手动查询它们。回复:数据库结构 - 这不是我的结构或数据,这只是一个例子,尽管感谢您的建议 您的问题明确表示您想要失去关系。这不是问题的重点吗? 也许我措辞不正确,我希望能够with 完整地查询关系,然后取消嵌套关系,这样我就不会发送可能重复的对象在 API 响应中 没有重复。 在第一个例子中,书和作者都是重复的以上是关于Laravel/Eloquent 规范化 JSON 响应的关系?的主要内容,如果未能解决你的问题,请参考以下文章
Laravel Eloquent - 使用 JSON 对象数组
Laravel - Eloquent to Json,然后对 json 对象进行 sortBy 不起作用
Laravel Eloquent,返回带有“belongsTo”对象的 JSON?
如何在 Laravel Eloquent 中获取包含数组的 JSON 对象的值?