如何在rails中的ruby中创建复杂的Json响应

Rad*_*Tuk 17 ruby json ruby-on-rails ruby-on-rails-3

我正在研究rails项目上的ruby,我想添加对Json的响应.

一个简单的方法是: -

def index
  @users = User.all
  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @users }
    format.json  { render :json => @users.to_json }
  end
end
Run Code Online (Sandbox Code Playgroud)

但是这有一些问题: -

  1. 我不想在json响应中给出整个用户对象,如密码哈希和缓存计数器属性.Facebook,推特属性等
  2. 我想在json对象中添加更多细节(考虑stackoverflow模型),例如每个用户的最新问题,每个用户给出的最新答案.而不是通过回形针存储在数据库中的图像名称,我想传递图像的完整网址.

所以问题是如何在index.json.erb文件中代码json响应,就像我们在index.html.erb中那样.根据需要格式化您自己的json响应.

编辑

def index
  @users = User.all
  respond_to do |format|
    format.html # index.html.erb
    format.xml  { render :xml => @users }
    format.json  { render :file => "index.json.erb", :content_type => 'application/json' }
  end
end
Run Code Online (Sandbox Code Playgroud)

index.json.erb文件: -

    <% @users.each do |user| %>
    {
      first_name: <%= user.first_name %>,
      last_name: <%= user.last_name %>  
    }

    <% end %>
Run Code Online (Sandbox Code Playgroud)

错误: -

模板丢失.

PS: - 我正在尝试使用创建此文件.这只是一个样本

编辑

在此输入图像描述

编辑

 { { first_name: Mohit , last_name: Jain } { first_name: Sahil Miglani, last_name: } { first_name: Hitesh Bansal, last_name: } { first_name: Sudhanshu, last_name: } { first_name: Saakshi, last_name: } { first_name: Kutta, last_name: } { first_name: bc, last_name: } { first_name: hey, last_name: } { first_name: fewhjfbwfb, last_name: vdsv } } 
Run Code Online (Sandbox Code Playgroud)

编辑

    [ { first_name: Mohit , last_name: Jain } , { first_name: Sahil Miglani, last_name: } , { first_name: Hitesh Bansal, last_name: } , { first_name: Sudhanshu, last_name: } , { first_name: Saakshi, last_name: } , { first_name: Kutta, last_name: } , { first_name: bc, last_name: } , { first_name: hey, last_name: } , { first_name: fewhjfbwfb, last_name: vdsv } ] 
Run Code Online (Sandbox Code Playgroud)

编辑,非常接近找出解决方案: -

    [
    <% @users.each_with_index do |user,index| %>
    {
        <%= "first_name".to_json.html_safe %>: <%= user.first_name.to_json.html_safe %>,
        <%= "last_name".to_json.html_safe %>: <%= user.last_name.to_json.html_safe %>  
    }
    <% unless index== @users.count - 1%>
    ,
    <% end %>
    <% end %>
    ]
Run Code Online (Sandbox Code Playgroud)

响应:-

    [

       -
       {
           first_name: "Mohit "
           last_name: "Jain"
       }
       -
       {
           first_name: "Sahil Miglani"
           last_name: null
       }
       -
       {
           first_name: "Hitesh Bansal"
           last_name: null
       }
       -
       {
           first_name: "Sudhanshu"
           last_name: null
       }
       -
       {
           first_name: "Saakshi"
           last_name: null
       }
       -
       {
           first_name: "Kutta"
           last_name: null
       }
       -
       {
           first_name: "bc"
           last_name: null
       }
       -
       {
           first_name: "hey"
           last_name: null
       }
       -
       {
           first_name: "fewhjfbwfb"
           last_name: "vdsv"
       }

    ]
Run Code Online (Sandbox Code Playgroud)

现在我想要的是将每个响应部分包含在用户数组中

Dev*_*n M 35

您可以通过在模型中实现代码来自定义输出:

def as_json(options={})
  super(:only => [:name, :email])
end
Run Code Online (Sandbox Code Playgroud)

然后在您的控制器中,您可以使用:

render :json => @user
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅" Rails to_json或as_json? ".


And*_*oni 20

您可以渲染json.erb文件并像普通模板一样使用它:

# file: app/views/your_controller/your_action.json.erb
{
  filed1: <%= @some_var %>,
  field2: <%= @another_var %>,
  fieldN: <%= @yet_another_var %>,
  data: <%= @some_data.to_json.html_safe %>
}
Run Code Online (Sandbox Code Playgroud)

在你的控制器中,调用显式渲染content_type:

render :file => "your_file.json.erb", :content_type => 'application/json'
Run Code Online (Sandbox Code Playgroud)

  • 您不使用视图来呈现数据结构.Rails有as_json是有原因的,它在创建JSON方面比人类更好.您拥有的代码在任何情况下都没用,除非您需要一些奇怪的非标准兼容的JSON,即使它完成了用户要求的操作,重新发明轮子绝对不是一个好习惯. (4认同)

Jes*_*ott 11

您可以发送JSON格式的选项:

  • :only (明确的属性列表)
  • :except (属性排除列表)
  • :methods (执行方法列表并包含其内容)
  • :include (关系)

如果要始终使用此JSON输出格式,请将它们放在as_json方法中(请参阅Devin的答案):

format.json  { render :json => @users.to_json{:only=>[:name, :email, :id], :methods=>[:last_question_answered], :include=>[:profile] }
Run Code Online (Sandbox Code Playgroud)


JCo*_*era 5

看看rabl gem,定制你的视图:

# app/views/posts/index.rabl
collection @posts
attributes :id, :title, :subject
child(:user) { attributes :full_name }
node(:read) { |post| post.read_by?(@user) }
Run Code Online (Sandbox Code Playgroud)

这将产生:

[{  post :
  {
    id : 5, title: "...", subject: "...",
    user : { full_name : "..." },
    read : true
  }
}]
Run Code Online (Sandbox Code Playgroud)