【问题标题】:How to customize to_json response in Rails 3如何在 Rails 3 中自定义 to_json 响应
【发布时间】:2010-09-15 15:13:15
【问题描述】:

我正在使用respond_with,并且所有内容都已正确连接以正确获取数据。我想以 DRY 方式自定义返回的 jsonxmlfoobar 格式,但我无法弄清楚如何使用有限的 :only: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 中添加了一些我没有意识到这种行为的东西。想法?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 response dry respond-with


    【解决方案1】:

    您可以在模型中覆盖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
    

    当使用respond_with 时,Rails 会处理其余的事情。不完全确定 options 设置为什么,但可能是您提供给 respond_with 的选项(:include:only 等)

    【讨论】:

    • 他想将 as_json、as_xml、as_foobar 全部更改在一个地方。
    • include 不使用as_json,这没有帮助。
    【解决方案2】:

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

    # 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 等是安全的。

    【讨论】:

    • 实际上,当 :only 未指定时,这可能只是默认值,否则它会改变使用 :only 的意图。哦,好吧,我的观点还是一样。
    • 重写 serializable_hash 更适合我在 Rails 3.2.8 中添加一些方法作为属性,谢谢!
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-13
      • 2011-06-09
      • 1970-01-01
      • 2011-06-25
      • 2022-11-21
      • 2011-02-04
      • 2012-05-19
      • 1970-01-01
      相关资源
      最近更新 更多