2009-09-03 4 views
13

Railsでリソースをルーティングするとき、オプションのフォーマット属性が自動的に生成されたルートに追加されます。これは、問題のリソースをXML、HTMLなどのいずれかで要求できるようにするためです。実際に許可されているフォーマットは通常コントローラでrespond_toを使用して記述します。Railsルートファイルのリソースフォーマットを制限する方法

多くの場合、HTMLをサポートしたいだけで、すべてのコントローラー内のすべてのアクションにrespond_to :htmlを書き込むオーバーヘッドのように感じます。そのため、routes.rbファイルにルートを作成するときに、許可されたコンテンツタイプに制限する方法がある場合は涼しいでしょう。

map.resources :users, :formats => :html 
map.resources :users, :formats => [:html, :xml] 
map.resources :users, :formats => {:index => :html, :show => [:html, :xml]}

これをネイティブプラグインまたはプラグイン経由で実現する方法はありますか?

P.S.これを回避する通常の方法は、問題を無視して、アクションにrespond_toを使用しないことです。しかし、これは実際に許可されたコンテンツタイプを制限しません。代わりに、可能なコンテンツタイプごとにviewsディレクトリ内にテンプレートが存在することが予想されます。要求されたときに存在しない場合、システムはHTTP 500エラーをスローします。

答えて

1

どちらの場合でも、HTTP 500エラーは必要ありませんか?例の2行目と同様に、HTMLの代わりにJSONを要求した場合やXMLがエラーコードではない場合は、適切な応答を返します。

+1

いいえ、500エラーは何かがサーバー上に間違っていた意味。コンテンツタイプがサポートされていない場合、サーバーエラーではありません。クライアントエラーです(クライアントは要求してはなりません)。 406が正しい応答コードになります。 「HTTP応答コード」を参照してください。http://www.sitepoint.com/blogs/2008/02/04/restful-rails-part-i/ –

+0

最後に.xmlまたは.htmlというタグを付ける場合は、 URLとその形式がサポートされていない場合、404が見つかりません。コンテンツタイプごとにURLを作成することでconnegの使用を無視しても構いませんが、acceptヘッダーに有効なコンテンツタイプがない場合はrepsonseコードを盗みます。 –

+0

Railsが実際にどのように機能するのかは分かりますが、ポイントがあるかもしれません。しかしそれにもかかわらず、これは私の質問のポイントではありません。私はまだ中央の場所(好ましくはルートファイル)にこれを指定したいと思っています - それでは、404または406がエラーで返されるかどうかにかかわらず、 –

3

私はあなたがこのような何かを行うことができると考えている:

respond_to do |format| 
    format.html 
    format.json { render :json => @things } 
    format.any { render :text => "Invalid format", :status => 403 } 
end 

場合は、ユーザーの要求HTMLまたはそれが必要として、それをやるJSONが、何か「無効な形式」のテキストをレンダリングします。

+0

これはうまくいくが、私は彼がルートから:形式を削除したいと思うと思う。 –

0

ではなく、やって:

def some_action 
    ... 
    respond_to do |format| 
    format.html 
    format.json { whatever } 
    format.any { whatever } 
    end 
end 

だけ使用します。

def some_action 
    ... 
end 

とRailsがsome_action.html.erbまたは任意のフォーマット要求された探しにデフォルト設定されます。 html以外のビューを定義しないと、要求された場合は他のすべてのフォーマットが失敗します。

+0

私は彼が: –

5

Railsはワイルドカードに相当するものを使用して "。:format"というフォーマットを処理するので、ルート側での処理を防ぐのが少し難しくなります。

これの代わりに、前のフィルタで非HTMLリクエストをキャッチするのはかなり簡単な方法です。ここでは、これが見えるかもしれない一つの方法です:

class ApplicationController < ActionController::Base 
    before_filter :check_format 

    private 

    def check_format 
     if request.format != Mime::HTML 
     raise ActionController::RoutingError, "Format #{params[:format].inspect} not supported for #{request.path.inspect}" 
     end 
    end 

end 

ActionController :: RoutingErrorsが賢明である404エラーとして処理されます。あなたがHTML以外のものをサポートする必要があるアクションを持っている場合に は、単に使用:

skip_before_filter :check_format, :only => ACTION_NAME 
6

あなたがスコープ内にそれらのルートをラップする必要がありますが、特定の形式に制限したい場合(例えばHTMLまたはjson)。残念なことに、この場合は制約が期待どおりに機能しません。

これは、このようなブロックの例です...

scope :format => true, :constraints => { :format => 'json' } do 
    get '/bar' => "bar#index_with_json" 
end 

詳しい情報はここで見つけることができます:https://github.com/rails/rails/issues/5548

この回答は、ここで私の前の回答からコピーされます。..

Rails Routes - Limiting the available formats for a resource

関連する問題