約束
你可以使用約束過濾可用的路徑。
有幾種方法可以使用約束,包括:
例如,基於請求的約束僅允許特定 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