Rails关联模型处理:如何将书籍对象数组转换为含作者分组与独立无作者书籍的JSON结构
解决Ruby on Rails中书籍数组转特定JSON结构的问题
嘿,这个需求我很熟悉,咱们一步步来实现它,保证高效又清晰!
核心思路
我们需要把给定的书籍数组分成两类处理:
- 关联了作者的书籍:按作者分组,每个作者对象带上属于它的书籍子集
- 无作者关联的独立书籍:直接提取所需字段
具体实现代码
步骤1:拆分书籍数组
首先把原数组分成有作者和无作者两个子数组:
# 假设你的书籍数组是这个变量 books = [ # 你的Book对象数组... ] # 拆分两组 books_with_author = books.select { |book| book.author_id.present? } books_without_author = books.reject { |book| book.author_id.present? }
步骤2:处理带作者的书籍(避免N+1查询)
为了不重复查询数据库,我们先批量获取所有关联的作者,再按author_id分组构建结构:
# 批量获取所有需要的作者,并存成哈希(key是author_id,value是作者对象) author_ids = books_with_author.pluck(:author_id).uniq authors_hash = Author.where(id: author_ids).index_by(&:id) # 按author_id分组书籍,然后构建作者带书籍的结构 author_entries = books_with_author.group_by(&:author_id).map do |author_id, grouped_books| author = authors_hash[author_id] { id: author.id, name: author.name, books: grouped_books.map { |book| { id: book.id, name: book.name } } } end
步骤3:处理独立书籍
直接提取无作者书籍的id和name字段:
independent_entries = books_without_author.map do |book| { id: book.id, name: book.name } end
步骤4:合并并转成JSON
把两部分结果合并,再转成你需要的JSON格式:
final_result = author_entries + independent_entries # 输出格式化后的JSON(可选,indent参数用来美化格式) puts final_result.to_json(indent: 2)
关键细节说明
- 使用
index_by把作者转成哈希:这一步是为了避免N+1查询(如果直接在循环里用Author.find(author_id),每个作者都会触发一次数据库查询),批量查询一次就够了 - 只使用给定数组中的书籍:因为你的需求里是基于现有书籍数组构建结构,而不是作者的全部书籍,所以用
group_by(&:author_id)来分组当前数组里的书籍,而不是用作者自带的books关联
这样运行后,就能得到你期望的JSON结构啦!
内容的提问来源于stack exchange,提问作者Alex Nikolsky
相关产品推荐
相关产品推荐

