2011-06-14 74 views
17

我在ruby on rails項目上工作,我想爲Json添加響應。如何在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 

但也有一些問題,這一點: -

  1. 我不希望給像密碼哈希JSON響應整個用戶對象和緩存計數器屬性。 Facebook,Twitter的屬性等
  2. 我想添加更多的細節在json對象(考慮stackoverflow模型)像每個用戶最新問題,每個用戶給出的最新答案。而不是通過回形針存儲在數據庫中的圖像名稱,我想傳遞圖像的完整url。

所以問題是如何編碼json在index.json.erb文件中響應,就像我們在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 

index.json.erb文件: -

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

    <% end %> 

錯誤: -

模板失蹤。

PS: - 我只是嘗試使用創建此文件。這僅僅是一個樣品

編輯

enter image description here

編輯

{ { 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 } } 

編輯

[ { 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 } ] 

編輯,發現相當接近了解決辦法: -

[ 
    <% @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 %> 
    ] 

響應: -

[ 

     - 
     { 
      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" 
     } 

    ] 

現在我想的是附上用戶陣列這個每個響應部分

+0

@YetAnotherGeek你想在用戶模型中看到什麼: - 關係?或屬性? – 2011-06-14 14:49:39

+1

對不起,我沒有完全閱讀你的問題,關於第一個部分問題,你可以使用:only和:除了散列來過濾掉內容。您還可以使用include包含來自其他表的數據。我不知道如何輕鬆修改數據,但不使用JSON gem。 [鏈接](http://apidock.com/rails/ActiveRecord/Serialization/to_json)。 – 2011-06-14 14:51:51

+0

你可以從你的對象生成哈希,並將其他所需的字段(鍵)添加到這個哈希 - 然後通過這個哈希來渲染:json => your_hash沒有明確告訴.to_json哈希 – bor1s 2011-06-14 14:52:50

回答

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 %> 
} 
在你的控制器

,請在致電content_type明確的渲染:

render :file => "your_file.json.erb", :content_type => 'application/json' 
+0

這就是它?(15個字符) – 2011-06-14 14:54:25

+0

你知道任何5分鐘的視頻嗎? – 2011-06-14 14:55:04

+0

JSON是一個數據結構,而不是視圖相關,所以我不認爲通過erb生成json是有意義的。這可能是一個很好的例子,如何不做事情。 – 2011-06-14 14:56:14

34

您可以通過在模型執行的代碼定製輸出:

def as_json(options={}) 
    super(:only => [:name, :email]) 
end 

然後在你的控制器,你可以使用:

render :json => @user 

有關更多信息,請參閱「Rails to_json or as_json?」。

+1

+1模型關注留在模型中。 – 2011-06-14 17:37:33

+1

這實際上應該如何完成。 – 2011-07-13 08:09:57

+2

+1。這應該是答案。 – GeorgeW 2012-12-14 12:58:54

11

您可以發送選項的JSON格式:

  • :only(屬性的顯式列表)
  • :except(屬性排除列表)
  • :methods(的執行方法列表,包括他們的內容)
  • :include(關係)

如果你想一直用這個JSON輸出格式,把它們放在as_json方法(見德文的答案):

format.json { render :json => @users.to_json{:only=>[:name, :email, :id], :methods=>[:last_question_answered], :include=>[:profile] } 
+0

如果我想對某些數據進行一些計算,該怎麼辦。是否有可能在index.json.erb中生成。如果是,那麼如何?任何5分鐘視頻屏幕視頻 – 2011-06-14 15:03:32

+1

將您的@user放到您想要的位置,然後進行渲染。 (先執行計算,然後返回爲json) – 2011-06-14 15:08:05

+0

問題是如果我想發送圖像url而不是圖像名稱。 – 2011-06-15 14:18:19

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

那將生成:

[{ post : 
    { 
    id : 5, title: "...", subject: "...", 
    user : { full_name : "..." }, 
    read : true 
    } 
}]