首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Rails中重写to_json?

如何在Rails中重写to_json?
EN

Stack Overflow用户
提问于 2010-04-04 02:49:10
回答 4查看 50.3K关注 0票数 95

更新:

这个问题没有得到适当的探讨。真正的问题在于render :json

在原始问题中粘贴第一个代码将产生预期的结果。然而,仍然有一个警告。请参阅此示例:

render :json => current_user

不是一样吗?

render :json => current_user.to_json

也就是说,render :json不会自动调用与User对象关联的to_json方法。事实上,如果to_jsonUser模型上被覆盖,render :json => @user将生成下面描述的ArgumentError

摘要

代码语言:javascript
复制
# works if User#to_json is not overridden
render :json => current_user

# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json

在我看来,这一切都很愚蠢。这似乎是在告诉我,当指定了类型Model#to_json时,render实际上并没有调用:json。有人能解释一下到底是怎么回事吗?

任何可以在这方面帮助我的genii都可能回答我的另一个问题:How to build a JSON response by combining @foo.to_json(options) and @bars.to_json(options) in Rails

原问题:

我在SO上看过一些其他的例子,但我没有做我想做的事情。

我在试着:

代码语言:javascript
复制
class User < ActiveRecord::Base

  # this actually works! (see update summary above)
  def to_json
    super(:only => :username, :methods => [:foo, :bar])
  end

end

我要把ArgumentError: wrong number of arguments (1 for 0)弄进来

代码语言:javascript
复制
/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json

有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-04-04 23:23:27

您得到的是ArgumentError: wrong number of arguments (1 for 0),因为需要用一个参数-- options散列来覆盖to_json

代码语言:javascript
复制
def to_json(options)
  ...
end

和更长的to_json**,解释** as_json**, rendering:**

在ActiveSupport 2.3.3中,添加了as_json来解决您遇到的问题。json的创建应该与json的呈现分开。

现在,每当对对象调用to_json时,都会调用as_json来创建数据结构,然后使用ActiveSupport::json.encode将该散列编码为JSON字符串。所有类型都会发生这种情况:对象、数值、日期、字符串等(参见ActiveSupport代码)。

ActiveRecord对象的行为与此相同。有一个默认的as_json实现,它创建一个包含所有模型属性的散列。你应该在你的模型中重写 as_json 来创建你想要的结构。与旧的to_json一样,as_json采用选项散列,您可以在其中以声明方式指定要包含的属性和方法。

代码语言:javascript
复制
def as_json(options)
  # this example ignores the user's options
  super(:only => [:email, :handle])
end

在您的控制器中,render :json => o可以接受字符串或对象。如果是字符串,则作为响应体传递;如果是对象,则调用to_json as_json ,从而触发如上所述的

因此,只要用as_json覆盖(或不用)正确地表示模型,那么显示一个模型的控制器代码应该如下所示:

代码语言:javascript
复制
format.json { render :json => @user }

这个故事的寓意是:避免直接调用to_json render ,让为你做这件事。如果需要调整JSON输出,请调用as_json**.**

代码语言:javascript
复制
format.json { render :json => 
    @user.as_json(:only => [:username], :methods => [:avatar]) }
票数 219
EN

Stack Overflow用户

发布于 2010-09-03 02:46:46

如果你在Rails3中遇到了这个问题,重写serializable_hash而不是as_json。这也将免费获得您的XML格式:)

我花了很长时间才弄明白。希望这能帮助到一些人。

票数 71
EN

Stack Overflow用户

发布于 2013-04-04 13:28:11

对于那些不想忽略用户选项但也添加了他们的选项的人:

代码语言:javascript
复制
def as_json(options)
  # this example DOES NOT ignore the user's options
  super({:only => [:email, :handle]}.merge(options))
end

希望这对任何人都有帮助:)

票数 36
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2572284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档