2012-03-01 25 views
0

我試圖實現自動完成,讓用戶從2種不同類型的模型列表中選擇。如何在rails3中調用to_json時包含類名?

這是我的控制器的外觀:

def ac 
    arr = [] 
    arr << Foo.all 
    arr << Bar.all 
    render json: arr.to_json 
end 

這使得:

[[{"id":1, "name":"foo name"}], [{"id":1, "name":"bar name"}]] 

如何包含類名和得到的東西是這樣的:

[ 
[{"id":1, "name":"foo name", "class_name":"Foo"}], 
[{"id":1, "name":"bar name", "class_name":"Bar"}] 
] 

+0

我想你忘記大括號圍繞屬性。除此之外,你有'ActiveRecord :: Base.include_root_in_json'設置爲'false'嗎?如果它是'true',那麼AR包含類名(強調並且解除消除,但是)作爲json散列的根元素。 – 2012-03-01 10:04:42

+0

@ KL-7對json的有效性沒有太多關注。已經閱讀了關於'ActiveRecord :: Base.include_root_in_json',但我認爲這是非常骯髒的方法,因爲它改變了應用程序範圍的設置。 – 2012-03-01 10:10:57

+0

最好讓你的問題在問題中有效,因爲他們現在沒有意義,這使得你很難理解你的意思。關於'include_root_in_json',我認爲它默認設置爲'true'。你自己改變了嗎? – 2012-03-01 10:13:58

回答

1

如果你不介意做一些額外的工作,你能做到像水木清華與as_json方法:methods選項(和to_json以及):

class Foo 
    def class_name 
    self.class.name 
    end 
end 

arr = Foo.all.map { |foo| foo.as_json(:methods => [:class_name]) } 
puts arr.to_json 
#=> [{ "id": 1, "name": "foo name", "class_name": "Foo" }] 

如果你有​​設置爲true(這是默認據我所知),那麼你會得到像

{ "foo": { "id": 1, "name": "foo name" } } 

哈希如果你希望它是完全的類名,你可以通過:root選項:

foo = Foo.last 
puts foo.to_json(:root => foo.class.name) 
#=> { "Foo": { "id": 1, "name": "foo name" } } 

請注意,這兩種解決方案都不允許您簡單地在記錄數組上調用to_json。爲了克服這一點,使默認包含class_name可以覆蓋serializable_hash方法模型那樣:

def serializable_hash(*) 
    super.merge('class_name' => self.class.name) 
end 

如果你把它包裝成一個模塊,您可以將其包含在任何你想要的模型,並得到class_name納入結果as_jsonto_json,而不會向這些方法傳遞任何額外的選項。如果您想在某些情況下排除class_name,您可以稍微修改實施以尊重:except選項。

0

結束了加入1個額外的步驟:

arr << Foo.all 
arr << Bar.all 
arr.flatten! 
arr=arr.collect{|itm| {"id":"#{itm.class.to_s}:#{itm.id}", "value":itm.name}} 

然後我就吐了出來:

render json: arr.to_json() 

,結果我得到:

[{"id":"Foo:1", "value":"Foo #1"},{"id":"Bar:1", "value":"Bar #1"}] 
相關問題