ruby-on-rails - 如何在 Rails 中覆盖 to_json?


更新:

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

原始问题中的第一个代码粘贴将产生预期的结果。但是,仍然有一个警告。看这个例子:

render :json => current_user

相同

渲染 :json => current_user.to_json

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

总结

# 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

这一切对我来说似乎很愚蠢。这似乎告诉我 render 在指定类型 :json 时实际上并没有调用 Model#to_json 。有人能解释一下这里到底发生了什么吗?

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


原问题:

我在 SO 上看到了一些其他示例,但我没有做我想要的。

我正在尝试:

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) in

/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json

有什么想法吗?

最佳答案

你得到 ArgumentError: wrong number of arguments (1 for 0) 因为 to_json 需要被一个参数覆盖,options哈希。

def to_json(options)
  ...
end

to_jsonas_json和渲染的详细解释:

在 ActiveSupport 2.3.3 中,添加了 as_json 以解决您遇到的问题。 json 的 creation 应该与 json 的 rendering 分开。

现在,只要在对象上调用 to_json,就会调用 as_json 来创建数据结构,然后使用 将该哈希编码为 JSON 字符串ActiveSupport::json.encode。这适用于所有类型:对象、数字、日期、字符串等(请参阅 ActiveSupport 代码)。

ActiveRecord 对象的行为方式相同。有一个默认的 as_json 实现,它创建一个包含所有模型属性的哈希。 您应该在模型中覆盖 as_json 以创建所需的 JSON 结构as_json 就像旧的 to_json 一样,采用选项哈希,您可以在其中指定要以声明方式包含的属性和方法。

def as_json(options)
  # this example ignores the user's options
  super(:only => [:email, :handle])
end

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

所以,只要您的模型正确地用 as_json 覆盖(或没有)表示,您显示一个模型的 Controller 代码应该如下所示:

format.json { render :json => @user }

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

format.json { render :json => 
    @user.as_json(:only => [:username], :methods => [:avatar]) }

https://stackoverflow.com/questions/2572284/

相关文章:

javascript - Angular 2 : How do you render HTML fr

python - 加载和解析具有多个 JSON 对象的 JSON 文件

ruby-on-rails - 在 Controller 中渲染 JSON

android - 从字符串转换为 JSON 对象 Android

c# - 如何将带有 JSON、jQuery 的复杂对象数组发布到 ASP.NET MVC Cont

javascript - 获取 Json 对象上的项目总数?

javascript - 浏览器原生 JSON 支持 (window.JSON)

javascript - 移除 JSON 元素

c# - 如何通过 JObject 进行枚举?

python - 使用 Django 1.7+ 和数据迁移加载初始数据