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

时间:2011-05-24 20:31:46

标签: ruby-on-rails ruby json activerecord

问题在于:我正在使用活动记录并返回一些照片对象。这些照片对象的最终消费者将成为一个移动应用程序。

响应需要返回缩略图版本,移动开发人员已经请求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_600":'image_600.jpg',
  "image_vga":'image_VGA.jpg',
  "image_full":'image.jpg'
 }
}

到目前为止,简单的方法是为每个缩略图创建列并使其发挥作用。我不喜欢被锁定,但因为如果我们想要不同的缩略图以后它会意味着向数据库添加列等等。我更喜欢在模型类中指定缩略图或者有一个单独的缩略图表桌子每排拇指。

我使用:method =>在连接中使用GROUP_CONCAT来查看delegate,composed_of。在to_json ..这些看起来都不像选项。有一个简单的方法吗?

基本模型示例:

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

1 个答案:

答案 0 :(得分:10)

您可以使用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序列化方法。