16

我正在使用respond_with并且一切都正确连接以正确获取数据。我想以 DRY 方式自定义返回的json,xmlfoobar格式,但我不知道如何使用有限的:onlyand来实现:include。当数据很简单时,这些很好,但是对于复杂的发现,它们达不到我想要的。

可以说我有一个has_many图片的帖子

def show
  @post = Post.find params[:id]
  respond_with(@post)
end

我想在响应中包含图像,这样我就可以这样做:

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

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

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

……但都是干的。在较旧的 Rails 项目中,我使用 XML 构建器来自定义输出,但在 json、xml、html 中复制它似乎不正确。我不得不想象 Rails 专家在 Rails 3 中添加了一些我没有意识到这种行为的东西。想法?

4

3 回答 3

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

Rails 在使用respond_with. 不完全确定options设置的内容,但可能是您提供给respond_with(:include:only)的选项

于 2011-01-26T11:18:12.887 回答
8

可能为时已晚,但我在 rails 文档中找到了一个更干燥的解决方案。这在我的简短测试中有效,但可能需要一些调整:

# 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

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

于 2011-02-08T23:15:08.793 回答
7

这不是 rails 3 的内置方式,但我发现了一个在 Rails 3 上积极维护的很棒的 gem:acts_as_api

于 2010-09-17T05:06:58.423 回答