2012-03-31 8 views
48

PUTをレールにして、204を取得しないようにします。私は更新するputを行うとき、私は204を取り戻す、しかしPARTから204を避けるレールで簡単な応答_with

class SomeController < ApplicationController 
    respond_to :json 

    def update 
    # ... 
    respond_with(some_object) 
    end 
end 

:私はこのパターンを使用しています。私はこれが完全に有効であることを認識していますが、私は明らかにコンテンツを元に戻したいと思います。私はこのようなある程度、それを上書きすることができます。

def update 
    respond_with(some_object) do |format| 
    format.json{render json: some_object} 
    end 
end 

が、これは、レールのためのハンズオン少しも思われます。 204を避け、完全なコンテンツを送り返すよう要求する慣用的な方法はありますか?これはRails 3.2です。

要約:204を避けるために、私は最大限慣用的なレールが必要です。

答えて

29

PUT/POSTでもJSONエンコードされたリソースを常に返すカスタムレスポンダを作成しました。

私はこのファイルをlib/responders/json_responder.rbに入れました。あなたの/libディレクトリにオートロードする必要があります。

module Responders::JsonResponder 
    protected 

    # simply render the resource even on POST instead of redirecting for ajax 
    def api_behavior(error) 
    if post? 
     display resource, :status => :created 
    # render resource instead of 204 no content 
    elsif put? 
     display resource, :status => :ok 
    else 
     super 
    end 
    end 
end 

ここで、この動作が必要なコントローラを明示的に変更するか、アプリケーションコントローラに配置してください。

class ApplicationController < ActionController::Base 

    protect_from_forgery 

    responders :json 

end 

JSONエンコードされたリソースをPUTに戻す必要があります。単純にやってと間違って何

+8

私はあなたが「応答」宝石は、あなたのコントローラで応答メソッドを使用できるようにする必要があることを追加します。 – iterion

3

def update 
    some_object = SomeObject.update() 
    render json: some_object 
end 
+2

適切なHTTPレスポンスコードやエラーが戻ってくることはありません –

+0

上記のコメントと同様に、 'update'が成功したかどうかのフィードバックは得られません。 – Leito

11

この動作は、HTTPの仕様に沿って落下する意図的なようで、「理想的な」あなたは結果を確認するために追加のGET要求をオフに発射されなければなりません。しかし、私は現実世界ではJSONを返すことにしたいと思います。

@ jpfuentes2の解決策は、以下のプルリクエストと非常によく似ていますが、主なバージョン間のアップグレードには本当に苦労する可能性があるため、レールの内部にパッチを当てることは躊躇します。テストをしていなければ(そして直面して、開発者はしばしばコントローラテストに夢中になります)。

参照

+0

あなたの答えをありがとう。あなたは正しいです、私はむしろフレームワークとの戦いを始めるよりも、 'JS'から別の' $ .get'を作っていきたいと思います。 – jibiel

6

だけ明確にするために、あなたがこれを行うにはレスポンダの宝石を必要としない...あなたはただ行うことができます。

設定を/初期化子/ responder_with_put_content。RB

class ResponderWithPutContent < ActionController::Responder 
    def api_behavior(*args, &block) 
    if put? 
     display resource, :status => :ok 
    else 
     super 
    end 
    end 
end 

、その後のいずれか(すべての更新アクションが影響されるために):

class ApplicationController < ActionController::Base 
    def self.responder 
    ResponderWithPutContent 
    end 
end 

またはあなたのアクションで:

def update 
    foo = Foo.find(params[:id]) 
    foo.update_attributes(params[:foo]) 
    respond_with foo, responder: ResponderWithPutContent 
end 
+0

あなたは私の日を救った。 (y) –

9

侵襲性の低い代替案として、あなたが渡すことができますコントローラ内でrespond_withメソッド呼び出しのjson:オプションにupdateアクション、このように:

def update 
    # ... 
    respond_with some_object, json: some_object 
end 

引数でオブジェクトを2回繰り返す必要がありますが、PUTリクエストの応答でオブジェクトのjson表現が必要になります。 render json:の方法を使用する必要がありますが、それはレスポンダの利益をもたらしません。

しかし、このような状況のコントローラがたくさんある場合、応答者をカスタマイズすると、受け入れられたanwserにjpfuentes2が表示されるようになります。しかし、迅速な単一のケースでは、この選択肢は簡単かもしれません。

出典:https://github.com/plataformatec/responders/pull/115#issuecomment-72517532

1

ないこの動作の大ファン。それを回避するために、私はrespond_withメソッドを使用しないように持っていた:

class SomeController < ApplicationController 
    respond_to :json 

    def update 
    # ... 
    respond_to do |format| 
     format.json { render(json: some_object, status: 200) } 
    end 
    end 
end 
関連する問題