在Rails中,如何使用视图呈现JSON?


125

假设您位于用户控制器中,并且想要获取显示请求的json响应,那么可以在视图/用户/目录中创建一个名为show.json的文件,并在用户之后#show操作完成后,它将呈现文件。

当前,您需要执行以下操作:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json{
      render :json => @user.to_json
    }
  end
end

但是,如果您可以创建一个show.json文件,它会像这样自动呈现,那就太好了:

def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

这将为我节省大量的悲伤,并且会消除我在控制器中渲染json时得到的那种可怕的肮脏感觉


现在看这篇文章,这似乎并不能为我节省很多,但是我有更复杂的案例,当我说这让我头疼时,请相信我
Matthew

1
在Rails 3中,您可以只调用format.json一个show.json.erb文件。看我的答案。
詹姆士·林

Answers:


64

您应该可以在自己的代码respond_to块中执行以下操作:

respond_to do |format|
    format.json 
    render :partial => "users/show.json"
end

这将在中呈现模板app/views/users/_show.json.erb


5
这很好,但是您会很快发现erb是生成json的痛苦方式。看看我的答案是否有其他选择。
tybro0103 2013年

1
有没有不使用局部的方法吗?
Wylliam Judd

55

尝试添加视图users/show.json.erb当您请求JSON格式时,应该渲染该视图,并且您也可以获得erb渲染它的额外好处,因此您的文件可能看起来像这样

{
    "first_name": "<%= @user.first_name.to_json %>",
    "last_name": "<%= @user.last_name.to_json %>"
}

9
您可能要使用@user.first_name.to_json而不是escape_javascript。JS允许的内容和严格意义上的 JSON 之间有一些细微的区别。(随着浏览器实现自己的JSON解析器,这些差异变得越来越重要。)
James A. Rosen 2010年

1
您可能应该将单引号更改为双引号,因为JSON(与JS不同)仅接受双引号字符串。
安倍·沃克

1
这很好,但是您会很快发现erb是生成json的痛苦方式。看看我的答案是否有其他选择。
tybro0103 2013年

我知道这是一个旧答案,但这是完全错误的。to_json将已经返回格式化的json字符串“”,因此生成的json永远不会带有多余的引号(““ value”“)。另外,如果用户名是nil,则生成的json将具有字符串“ null”作为值。同样,<%=使用html转义,这会破坏输入数据中的html字符。
d4n3

我认为您还需要删除引号,<%= xyz.to_json %>否则您将剩下多余的引号。
akostadinov

32

正如其他人提到的那样,您需要一个users / show.json视图,但是对于模板语言,有一些选项需要考虑...

ERB

开箱即用。非常适合HTML,但是您很快就会发现它对JSON很糟糕。

拉比

好的解决方案。必须添加一个依赖项并学习其DSL。

JSON构建器

与RABL的交易相同:好的解决方案。必须添加一个依赖项并学习其DSL。

纯红宝石

Ruby在生成JSON方面很棒,而且您可以调用to_jsonHash或AR对象,因此没有什么新的知识可学习。只需为模板注册.rb扩展名(在初始化程序中):

ActionView::Template.register_template_handler(:rb, :source.to_proc)

然后创建视图users / show.json.rb:

@user.to_json

有关此方法的更多信息,请参见http://railscasts.com/episodes/379-template-handlers


7
请注意,在rails 4中,默认情况下注册了.ruby模板处理程序github.com/rails/rails/commit/de1060f4e02925c12004f2,因此您可以跳过注册.rb并命名文件用户/show.json.ruby。
蒂姆·迪金斯

1
另外,为了进一步更新,json.builder已由github.com/rails/jbuilder取代。
蒂姆·迪金斯

27

如果您正在寻找ERb语法的替代方案,RABL可能是解决此问题的最佳解决方案。其他解决方案json_builder和argonaut似乎都已过时,并且如果不进行一些修补,将无法在Rails 3.1中使用。

RABL可以通过gem获得,也可以查看GitHub存储库;也是很好的例子

https://github.com/nesquena/rabl


21

仅为了更新此答案,以便其他人碰巧出现在此页面上。

在Rails 3中,您只需要在创建文件views/users/show.json.erb。该@user对象将可用于视图(就像html一样。)您甚至不需要to_json了。

总而言之,这只是

# users contoller
def show
  @user = User.find( params[:id] )
  respond_to do |format|
    format.html
    format.json
  end
end

/* views/users/show.json.erb */
{
    "name" : "<%= @user.name %>"
}

1
我在1.5年前回答了这个问题。如今,只要需要JSON等,我就可以使用response_with respond_with @user, only: [:name]。有关更多信息,请参考本教程
James Lim

1
只是添加到此答案中,实际上这很危险,原因有两个:允许从用户数据中进行注入,因为它不会转义换行符和反斜杠,并且<%= html会转义数据,因此,例如Sean O'Connor将使用他的名字to向肖恩·奥康纳(Sean O’Connor)。
d4n3

10

只需添加show.json.erb包含内容的文件

<%= @user.to_json %>

有时,当您需要一些控制器中不可用的其他辅助方法时,即image_path(@user.avatar)在JSON中生成其他属性的方法时,它很有用:

<%= @user.attributes.merge(:avatar => image_path(@user.avatar)).to_json %>

8
需要<%= raw(@user.to_json) %>避免HTML转义。我所做的是只要能给我想要的东西,我就依赖to_json,但是当我想做其他事情时,我通常使用a作为模板{ :blah => @user.the_blah }.to_json
clacke


0

我对RoR感到陌生,这是我发现的。您可以直接呈现json格式

def YOUR_METHOD_HERE
  users = User.all
  render json: {allUsers: users} # ! rendering all users
END
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.