如何在Rails 3中自定义to_json响应

con*_*are 16 ruby-on-rails dry response respond-with ruby-on-rails-3

我正在使用respond_with,所有内容都正确连接,以正确获取数据.我想自定义的返回json,xml以及foobar格式在干燥的方式,但我无法弄清楚如何使用有限的做:only:include.当数据很简单时,这些都很棒,但是对于复杂的发现,它们不符合我的要求.

可以说我有一个帖子哪个has_many图像

def show
  @post = Post.find params[:id]
  respond_with(@post)
end
Run Code Online (Sandbox Code Playgroud)

我希望将图像包含在响应中,以便我可以这样做:

def show
  @post = Post.find params[:id]
  respond_with(@post, :include => :images)
end
Run Code Online (Sandbox Code Playgroud)

但我真的不想发送整个图像对象,只是网址.除此之外,我真的希望能够做到这样的事情(伪代码):

def show
  @post = Post.find params[:id]
  respond_with(@post, :include => { :foo => @posts.each.really_cool_method } )
end

def index
  @post = Post.find params[:id]
  respond_with(@post, :include => { :foo => @post.really_cool_method } )
end
Run Code Online (Sandbox Code Playgroud)

......但是一切都干了.在较旧的rails项目中,我使用XML构建器来自定义输出,但是在json,xml,html中复制它看起来不对.我不得不想象铁路专家在Rails 3中放了一些东西,我没有意识到这种行为.想法?

Per*_*mal 21

您可以as_json在模型中覆盖.就像是:

class Post < ActiveRecord::Base
  def as_json(options = {})
    {
      attribute: self.attribute, # and so on for all you want to include
      images:    self.images,    # then do the same `as_json` method for Image
      foo:       self.really_cool_method
    }
  end
end
Run Code Online (Sandbox Code Playgroud)

Rails在使用时会处理其余部分respond_with.不完全确定什么options设置,但可能你给的选项respond_with(:include,:only等等)

  • 他想在一个地方改变as_json,as_xml,as_foobar. (2认同)

Ner*_*ter 8

可能为时已晚,但我发现了一个更加干燥的解决方案,通过rails docs进行挖掘.这适用于我的简短测试,但可能需要一些调整:

# This method overrides the default by forcing an :only option to be limited to entries in our
# PUBLIC_FIELDS list
def serializable_hash(options = nil)
  options ||= {}
  options[:only] ||= []
  options[:only] += PUBLIC_FIELDS
  options[:only].uniq!
  super(options)
end
Run Code Online (Sandbox Code Playgroud)

这基本上允许您拥有公共API允许的字段列表,并且您不会意外地暴露整个对象.您仍然可以手动公开特定字段,但默认情况下,您的对象对.to_json,.to_xml等是安全的.


con*_*are 7

它不是rails 3内置的方式,但我在Rails 3上发现了一个很棒的宝石:acts_as_api