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

如何为Rails的Event模型构建嵌套JSON格式(含/不含Jbuilder)

刚好之前做过类似的需求,给你整理两种靠谱的实现方式,不管用不用Jbuilder都能搞定:

方法一:Ruby原生哈希拼接(不依赖额外库)

这种方式直接用Ruby和Rails的原生方法,适合结构不算特别复杂的场景,不用引入Jbuilder也能快速实现。

步骤说明:

  1. 按类别分组事件:假设你的Event模型有category字段(存"quiz"、"dance"这类字符串),先把所有事件按类别分组:
events_by_category = Event.all.group_by(&:category)
  1. 构建目标哈希结构:遍历分组后的结果,把每个类别转换成你需要的嵌套格式:
result_hash = {
  event: events_by_category.each_with_object({}) do |(category_name, events), final_hash|
    # 这里的name和desc可以根据类别动态赋值,比如从Category模型取,或者用默认值
    category_info = {
      name: "", # 示例:Category.find_by(identifier: category_name)&.display_name || ""
      desc: "",
      events: events.map { |event| { name: event.name, desc: event.desc } }
    }
    final_hash[category_name] = category_info
  end
}
  1. 转成JSON:最后调用to_json就能得到你要的格式:
result_hash.to_json

优化点:

如果你的项目里有Category模型(和Event是一对多关联),建议用预加载来避免N+1查询,性能更好:

# 先预加载所有类别及其关联的事件
categories = Category.includes(:events).all

result_hash = {
  event: categories.each_with_object({}) do |category, final_hash|
    final_hash[category.name] = {
      name: category.name,
      desc: category.desc,
      events: category.events.map { |e| { name: e.name, desc: e.desc } }
    }
  end
}
方法二:使用Jbuilder(灵活易维护)

Jbuilder是Rails官方推荐的JSON构建工具,写起来更直观,尤其是后续结构需要调整时,维护成本更低。

步骤说明:

  1. 确保Jbuilder已安装:检查Gemfile里有没有gem 'jbuilder',没有的话加上然后运行bundle install。
  2. 控制器准备数据:在对应的控制器action里,把分组好的数据传给视图:
# 比如EventsController的index方法
def index
  @events_by_category = Event.all.group_by(&:category)
  # 如果有Category模型,推荐用:@categories = Category.includes(:events).all
end
  1. 编写Jbuilder模板:在app/views/events/index.json.jbuilder里编写JSON结构:
json.event do
  @events_by_category.each do |category_name, events|
    # 用set!来动态设置键名(比如"quiz"、"dance")
    json.set! category_name do
      json.name "" # 同样可以动态赋值,比如Category.find_by(name: category_name)&.name
      json.desc ""
      json.events events do |event|
        json.name event.name
        json.desc event.desc
      end
    end
  end
end

如果用Category模型的话,模板可以改成更简洁的版本:

json.event do
  @categories.each do |category|
    json.set! category.name do
      json.name category.name
      json.desc category.desc
      json.events category.events do |event|
        json.name event.name
        json.desc event.desc
      end
    end
  end
end

额外提示:

  • 如果要过滤掉没有子事件的类别,可以在分组时加个过滤:events_by_category.reject { |_, events| events.empty? }
  • 要是需要对JSON做格式化(比如缩进),可以在to_json里加参数:result_hash.to_json(indent: 2),Jbuilder默认会输出格式化后的JSON。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:59:47