我正在编写一个应用程序,我希望所有 HTML 请求都由同一 Controller 操作处理。我还有一些其他特定于 JSON 的路由。这是我的路线:
Blog::Application.routes.draw do
constraints format: :json do
resources :posts
end
match "(*path)" => "web#index"
end
问题在于 constraints
被解释为“此路由仅适用于指定的格式”,而不是“如果请求不符合指定的格式,则跳过此路由并尝试下一个路由。 ”
换句话说,在浏览器中导航到 /posts 会出现 406 Not Acceptable,因为 URL 仅限于 JSON 格式。相反,如果请求是 HTML,我希望它落到 web#index,如果请求是 JSON,我希望它到达资源丰富的路由。如何实现这一目标?
(使用 Rails 3.2.9。)
最佳答案
我思考过这个问题,并得出了一些结论。
- 您可能不希望所有路由都返回单页应用 HTML,因为理想情况下您希望从某些路径返回 HTTP 404 状态代码。
- 您的 HTTP 路由将与 JSON 路由不同
- 您绝对应该将不同的格式路由到不同的 Controller
- 在 Rails 路由器中定义所有 HTML 路由可能会很有利,这样您就可以使用它来生成 JavaScript 路由器。至少有一个 gem 可以做到这一点
- Rails 没有此功能,而此 gem https://github.com/svenfuchs/routing-filter看起来确实不是正确的工具。这是我的尝试:Rails routing-filter route all html requests to one action
- 必须在模块 Api 下命名 JSON API 以避免路由冲突并不是坏事。
- 您的单页应用中不得有 Google 可见的内容,否则您将因重复内容而被禁止。
我采取了稍微不同的方法,这并不能真正回答问题,但我认为它有一些优点:
这是我的 config/routes.rb
FooApp::Application.routes.draw do
# Route all resources to your frontend controller. If you put this
# in a namespace, it will expect to find another frontend controller
# defined in that namespace, particularly useful if, for instance,
# that namespace is called Admin and you want a separate single page
# app for an admin interface. Also, you set a convention on the names
# of your HTML controllers. Use Rails's action_missing method to
# delegate all possible actions on your frontend controllers.
def html_resources(name, options, &block)
resources(name, options.merge(:controller => "frontend"), &block)
end
# JSON API
namespace :api do
resources :things, :except => [:edit, :new]
end
# HTML
html_resources :things, :only => [:edit, :new, :index, :show] do
get :other_action
end
end
class FrontendController < ApplicationController
def action_missing(*args, &block)
render :index
end
end
关于ruby-on-rails - rails : Routing to a different controller based on request format,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13754195/