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 对象的值?

Laravel Eloquent 搜索 JSON 数组以获取特定列的值

Laravel Eloquent 在 JSON 列中查找日期在某个范围内的所有记录