2014-06-17 63 views
0

我正在構建JSON API,至今未找到有關如何處理使用RABL模板的控制器中保存錯誤的好建議。我真的很感激任何關於改進代碼的建議。使用RABL模板進行錯誤響應

這是我目前如何處理未能保存:

# products_controller.rb 
    def create 
     @product = Product.new(params[:product]) 
     unless @product.save 
     render json: @product.errors, status: :unprocessable_entity 
     end 
    end 

這是我的Rabl的模板:

# product.json.rabl 
    object @product 
    attributes :name, :price 

它的工作原理,但行 '除非@ product.save' 不覺得不對勁......下面是測試:

# products_controller_test.rb 
    test 'create a product' do 
     assert_difference 'Product.count', 1 do 
     post :create, product: { name: 'Apple', price: 1.25 }, format: :json 
     end 
     assert_response :success 
    end 

    test 'failing product creation' do 
     Product.any_instance.stubs(:save).returns(false) 
     assert_no_difference 'Product.count' do 
     post :create, product: { name: 'Apple' }, format: :json 
     end 
     assert_response 422 
    end 

更新

感謝@KonradOleksiuk我能夠在一個更可讀的方式重寫控制器:

if @product.save 
     respond_with @product 
    else 
     respond_with @product, status: :unprocessable_entity 
    end 

我也必須確保錯誤是越來越重視的JSON響應:

# product.json.rabl 
    object @product 
    attributes :name, :price 

    node :errors do |o| 
     o.errors 
    end 

回答

1

這取決於您想要達到的格式。您始終可以在rabl模板中使用node以在線渲染錯誤。它已經由寶石的合作者解釋:https://github.com/nesquena/rabl/issues/222#issuecomment-5413021

感謝這一點,您可以避免except語句並僅使用視圖。

+0

Thanks @Konrad!這是否意味着如果json錯誤屬性不爲空以查看是否發生了錯誤,那麼您需要檢查前端?如果我理解正確,兩種情況下的響應狀態都是200(:ok)? – sakovias

+0

使用顯式渲染方法 - 是的。但是,您可以使用respond_with方法,如果存在錯誤對象,將返回422 - http://api.rubyonrails.org/classes/ActionController/Responder.html(自定義選項標頭) – konole

+0

感謝respond_with提示。不幸的是,無法升級您的解決方案。 – sakovias

0
def create 
    @product = Product.new(params[:product]) 
    @product.save 
    respond_with @product 
end 

工作在這兩種情況下成功和失敗保存。 如果保存失敗respond_with將渲染帶@product錯誤的json,在成功的情況下它會渲染rabl模板

+0

在成功和失敗的情況下,恐怕狀態碼都是200:OK。 – sakovias

+0

否,失敗的情況下代碼是422不可處理的實體 – kashlo