约束
你可以使用约束过滤可用的路径。
有几种方法可以使用约束,包括:
例如,基于请求的约束仅允许特定 IP 地址访问路由:
constraints(ip: /127\.0\.0\.1$/) do
get 'route', to: "controller#action"
end
查看其他类似的示例 ActionDispatch::Routing::Mapper::Scoping 。
如果你想做一些更复杂的事情,你可以使用更高级的约束并创建一个类来包装逻辑:
# lib/api_version_constraint.rb
class ApiVersionConstraint
def initialize(version:, default:)
@version = version
@default = default
end
def version_header
"application/vnd.my-app.v#{@version}"
end
def matches?(request)
@default || request.headers["Accept"].include?(version_header)
end
end
# config/routes.rb
require "api_version_constraint"
Rails.application.routes.draw do
namespace :v1, constraints: ApiVersionConstraint.new(version: 1, default: true) do
resources :users # Will route to app/controllers/v1/users_controller.rb
end
namespace :v2, constraints: ApiVersionConstraint.new(version: 2) do
resources :users # Will route to app/controllers/v2/users_controller.rb
end
end
一个表单,几个提交按钮
你还可以使用表单的提交标记的值作为约束来路由到不同的操作。如果你有一个包含多个提交按钮的表单(例如预览和提交),你可以直接在 routes.rb
中捕获此约束,而不是编写 javascript 来更改表单目标 URL。例如,使用 commit_param_routing gem,你可以利用 rails submit_tag
Rails submit_tag
第一个参数允许你更改表单提交参数的值
# app/views/orders/mass_order.html.erb
<%= form_for(@orders, url: mass_create_order_path do |f| %>
<!-- Big form here -->
<%= submit_tag "Preview" %>
<%= submit_tag "Submit" %>
# => <input name="commit" type="submit" value="Preview" />
# => <input name="commit" type="submit" value="Submit" />
...
<% end %>
# config/routes.rb
resources :orders do
# Both routes below describe the same POST URL, but route to different actions
post 'mass_order', on: :collection, as: 'mass_order',
constraints: CommitParamRouting.new('Submit'), action: 'mass_create' # when the user presses "submit"
post 'mass_order', on: :collection,
constraints: CommitParamRouting.new('Preview'), action: 'mass_create_preview' # when the user presses "preview"
# Note the `as:` is defined only once, since the path helper is mass_create_order_path for the form url
# CommitParamRouting is just a class like ApiVersionContraint
end