2011-08-30 55 views
6

我知道如何全局禁用根元素,la Rails 3.1 include_root_in_json或使用ActiveRecord::Base.include_root_in_json = false,但我只想爲幾個JSON請求(不是全局的)執行此操作。Rails:僅在特定的控制器操作中禁用JSON中的根目錄?

到目前爲止,我一直在做這樣的:

@donuts = Donut.where(:jelly => true) 
@coffees = Coffee.all 
@breakfast_sandwiches = Sandwich.where(:breakfast => true) 

dunkin_donuts_order = {} 
dunkin_donuts_order[:donuts] = @donuts 
dunkin_donuts_order[:libations] = @coffees 
dunkin_donuts_order[:non_donut_food] = @breakfast_sandwiches 

Donut.include_root_in_json = false 
Coffee.include_root_in_json = false 

render :json => dunkin_donuts_order 

Donut.include_root_in_json = true 
Coffee.include_root_in_json = true 

有大約5情況下,我有一個以上的模型要做到這一點,有時,它不覺得乾淨所有。我試圖把它放在around_filter的位置上,但是例外情況正在打破這個流程,而且這也變得多毛。

必須有更好的方法!

+0

這並不直接回答你的問題,但它確實回答了我來這裏尋找的問題:你可以抑制個人對'to_json'調用的根,例如'Donut.to_json(root:false)' – Lambart

回答

2

答案不幸的是,沒有。

是的,你以上所做的事情可以說是做得更好。不,Rails不會讓您在每個操作的基礎上添加根目錄。 JSON渲染只是沒有考慮到這種靈活性而構建的。

話雖這麼說,這裏就是我想要做的:

  1. 設置對於那些具有路徑依賴的作用(如DonutCoffee以上)車型include_root_in_jsonfalse
  2. 重寫as_json以允許更大的靈活性。這裏有一個例子:

    # in model.rb 
    def as_json(options = nil) 
        hash = serializable_hash(options) 
        if options && options[:root] 
         hash = { options[:root] => hash } 
        else 
         hash = hash 
        end 
    end 
    

    這個例子將讓這個你可以選擇通過一個根,但默認是沒有根。你也可以用另一種方式寫它。

  3. 由於您將覆蓋as_json,因此您必須適當修改渲染調用。所以,對於Donut,你會做render :json => @donut.to_json

希望這會有所幫助!

+0

謝謝。我停止了自己的腳步,轉而使用[RABL](https://github.com/nesquena/rabl),並且從未回頭。好多了! – neezer

+0

很好的答案。但是你不必調用as_json()。to_json,因爲to_json自動調用你的as_json覆蓋。 –

+0

謝謝,@NadaAldahleh。我已經在我的回答中澄清了這一點。 –

1

您可以設置include_root_in_json每個模型實例,它不會影響類的(見class_attribute在軌API來此行爲的描述)。因此,您可以在課程級別設置合理的默認值,然後在相關控制器中的每個實例上設置不同的值。

實施例:

@donuts = Donut.where(:jelly => true).each {|d| d.include_root_in_json = false } 

爲了方便起見,可以創建接受模型實例的數組,並設置在所有這些值的工具方法。

相關問題