如何在不嵌套的情况下从关系中向渲染的JSON添加属性?

问题描述

| 问题出在这里:我正在使用活动记录并返回一些照片对象。这些照片对象的最终消费者将是移动应用程序。 响应需要返回缩略图版本,移动开发人员已要求返回的JSON如下所示。
{
\"root_url\":\'http://place.s3.amazonaws.com/folder/\',\"image_300\":\'image_300.jpg\',\"image_600\":\'image_600.jpg\',\"image_vga\":\'image_VGA.jpg\',\"image_full\":\'image.jpg\'
}
而不是这样:
{
\"root_url\":\'http://place.s3.amazonaws.com/folder/\',\"thumbnails\": {
  \"image_300\":\'image_300.jpg\',\"image_full\":\'image.jpg\'
 }
}
到目前为止,最简单的方法是为每个缩略图创建列,然后哇!我不喜欢被限制在其中,因为如果以后我们想要不同的缩略图,那就意味着向数据库中添加列,等等。我更愿意要么只是在模型类中指定缩略图,要么用一个单独的表来包含缩略图桌子的每一行一个大拇指。 我已经看过委托,committed_of,在联接中使用GROUP_CONCAT ..,在to_json中使用:method => ..这些都不是选项。是否有捷径可寻? 基本模型示例:
class Photo < ActiveRecord::Base
  has_many :thumbnails,:as => :thumbs_for #polymorphic
end

class Thumbnail < ActiveRecord::Base
  # columns = name,filename
  belongs_to :thumb_for,:polymorphic => true
end
到目前为止,根据jesse reiss的回答,结果看起来像这样
def as_json(options)
  options ||= {} #even if you provide a default,it ends up as nil
  hash = super(options.merge({:include => :thumbnails}))
  if thumbs = hash.delete(:thumbnails)
    thumbs.each {|t| hash.merge!({t[\'name\']=>t[\'filename\']})}
  end
  hash
end
    

解决方法

您可以使用
as_json
方法非常简单地自定义对象的json序列化。 为此,您可以执行以下操作:
def as_json(*args)
  hash = super(*args)
  hash.merge!(hash.delete(\"thumbnails\"))
end
或者你可以超级手动地做
def as_json(*args)
  hash = super()
  thumbnails.each do |thumb|
    # build thumbnail json
  end
end
您不必依赖ActiveRecord的超级简单化json序列化方法。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...