我想在控制器中定義一個before_filter,但總是要最後執行它。有沒有辦法強制before_filter總是最後執行?
我知道append_before_filter,但我想在模塊中指定此過濾器,其他類可能稍後會添加其他before_filters。
有沒有辦法做到這一點?
我想在控制器中定義一個before_filter,但總是要最後執行它。有沒有辦法強制before_filter總是最後執行?
我知道append_before_filter,但我想在模塊中指定此過濾器,其他類可能稍後會添加其他before_filters。
有沒有辦法做到這一點?
我不知道一個優雅的方式來實現這一點。但是,使用一些橫向思維......你可以確保你的所有控制器都使用prepend_before_filter
。這樣,如果您的模塊使用before_filter
,您將知道它始終是最後一個過濾器,因爲控制器將始終將其過濾器添加到過濾器鏈的開頭。
根據rails API,默認的「before_filter」是「append_before_filter」的別名,它將過濾器附加到filter_chain列表的末尾。我會說有一個合理的假設,如果您在控制器中正確地命令您的過濾器,他們將被執行,以便他們列出。正如前面的答案所示,還有一個「prepend_before_filter」,可確保您添加的過濾器位於filter_chain的前端。
您可以在模塊中覆蓋before_filter
或使self.included
回調掛鉤聲明alias_method_chain :before_filter, :final_filter
。對於您希望能夠跨越多個版本的Rails進行移植的代碼,或者您將發佈要在其他上下文中使用的代碼的情況,建議不要這樣做。
下面是一個簡單的模塊,它允許在整套before_filters之後執行任意代碼。通過一些小小的工作,你可以清理它,這樣在這裏執行一個特殊的after_before_filters
隊列(用適當的暫停行爲,等等)。
module OneLastFilterModule
def self.included(base)
base.class_eval do
def perform_action_without_filters_with_one_last_filter
#
# do "final" before_filter work here
#
perform_action_without_filters_without_one_last_filter
end
alias_method_chain :perform_action_without_filters, :one_last_filter
end
end
end
請注意,您應該小心這樣做,因爲控制器本身可能會根據聲明順序對過濾器順序進行假設。