【问题标题】:How to extract all attributes with Rails Jbuilder?如何使用 Rails Jbuilder 提取所有属性?
【发布时间】:2025-12-15 05:10:02
【问题描述】:

一直在jbuilder.json模板中写这样的代码很痛苦:

json.extract! notification, :id, :user_id, :notice_type, :message, :resource_type, :resource_id, :unread, :created_at, :updated_at

所以我想这样编码;

json.extract_all! notification

我发现我可以像下面的代码那样做,但它们对我来说仍然有点冗长。

notification.attributes.each do |key, value|
  json.set!(key, value)
end

有没有更好的办法?

【问题讨论】:

  • 可能这个简单一点,json.extract! notification, *notification.attributes.keys 但是如果Jbuilder有这样的方法,我想用它来代替。

标签: ruby-on-rails jbuilder


【解决方案1】:

也许你可以使用json.merge!

json.merge! notification.attributes

https://github.com/rails/jbuilder/blob/master/lib/jbuilder.rb#L277

【讨论】:

  • 谢谢!这正是我想要的!!只是,我的 Rails 版本是 4.0,所以我应该先升级到 4.1。
  • 我只是尝试在 Rails 4.1 中使用这种方法,但不幸的是它似乎没有合并到 4.1 中。所以我决定再等一会儿。
  • 您使用的是最新版本的 jbuilder 吗?试试bundle update jbuilder
  • 哦,jbuilder 只是一个 gem,目前与 Rails 版本无关。该方法适用于 jbuilder 2.1.1!谢谢你的麻烦。
  • 小心泄露敏感属性。添加reject 以过滤出一个或多个:json.merge! user.attributes.reject {|k, v| k == 'encrypted_password' }
【解决方案2】:

我正在使用 jbuilder 1.5.0 并合并!没用,但我找到了另一种语法:

json.(notification, *notification.attributes.keys)

【讨论】:

  • 正如@Dakuan 所说,这符合JBuilder.key_format 设置,如果您将密钥从snake_case 转换为camelCase,这是必要的。根据this railscast,我相信这种语法在某些版本的ruby中不起作用,在这种情况下,工作语法是json.extract! notification, *notification.attributes.keys
【解决方案3】:

在@uiureo 的回答中添加更多内容

假设你的 Notification 有某种类型的图片上传器(例如carrierwave、paperclip)

那么下面的版本将不会返回你的上传者对象,那么你如何获得图片的url?

json.merge! notification.attributes

notification.attributes是对象的hash转换,它会返回挂载的uploader列值而不是url。

示例响应

notification: Object {
   title: "hellow world"
   img: "sample.png"
}

试试这个

json.merge! notification.as_json

这将作为另一个对象返回挂载的列,您可以在其中查询 url。

示例响应

notification: Object {
   title: "hellow world"
   img: Object {
       url: "https://www.example.com/sample.png"
   }
}

【讨论】:

    【解决方案4】:

    你可以看看json.except!

    json.except! @resource, :id, :updated_at

    json.except! @resource

    https://github.com/chenqingspring/jbuilder-except

    【讨论】:

      【解决方案5】:

      如果您想排除任何属性。例如:created_atupdated_at

      json.merge! notification.attributes.reject{ |key, _| key.in?(['created_at', 'updated_at']) }
      

      【讨论】:

        【解决方案6】:

        我就是这样做的

        json.property  do
          Property.column_names.each do |name|
             json.set! name, @property.try(name)
          end
        
          # has_ones:
          json.contact @property.contact
        end
        

        很容易看到发生了什么,添加逻辑以省略字段等这样做。

        【讨论】: