6

Reasons™ のために、1 つのコントローラーで html リクエストを処理し、別のコントローラーで json API リクエストを処理したいと考えています。

私は私のルートでこれを持っています:

scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end
constraints format: :html do
  resources :users
end

これは、URL に接尾辞が/users.json付いている場合にうまく機能します。私のアラを通り抜けます。Api::UsersControllerapi_users_path/users.htmlUsersControllerusers_path

ただし、URL にサフィックスがない場合、これは期待どおりに動作しません。制約をラムダショーとして実装すると、問題が発生します。

#=> visiting /users

scope module: :api, as: :api do
  constraints ->(request){ puts "In api: #{request.format}"; request.format == :json } do
    resources :users
  end
end
constraints ->(request){ puts "In html: #{request.format}"; request.format == :html } do
  resources :users
end

#=> In api: text/html
#=> (request.format == :json) => false

それでも、APIコントローラーで終了します。

カスタムの制約クラスやラムダなどをいじっても、一致する制約がない場合にレールが定義された最初のルートを選択するのを妨げることはありません。

URL にサフィックスがない場合にキャッチする制約を作成する方法が見つかりません。また、そうしなければならないような気がしません– <code>request.format == :html は、ナビゲートしているときに true を報告しますに/users。2 番目の制約がそれをキャッチしないのはなぜですか?

また、これら 2 つの順序を変更することでこれを「修正」することもできますが、制約が正しく機能しない理由を知りたいです。

URLサフィックスだけでなく、フォーマットが何であれ効果的に切り替えるために、これらの制約を異なる方法で強制する方法を知っている人はいますか、またはフォーマットサフィックスに対応しない明示的な制約がありますか?

4

3 に答える 3

1

ジェレミーの答えを拡張する..ルートのAPIスコープの前にユーザーのデフォルトのhtmlルートを挿入するとどうなりますか?

お気に入り、

resources :users
scope module: :api, as: :api do
  constraints format: :json do
    resources :users
  end
end

奇妙なことに、これは私にとってはうまくいきます!

于 2013-10-14T14:41:30.223 に答える
1

接尾辞のないデフォルト形式を に設定するjsonと、ニーズに対応できます。

scope module: :api, as: :api, defaults: { format: :json} do
  constraints format: :json do
    resources :users
  end
end

明示的な .html サフィックス リクエストのみがこのリソースに到達します

resources :users
于 2014-11-04T22:25:00.120 に答える