2013-12-20 31 views
0

我正在使用通用控制器爲REST風格的操作提供默認功能,但在需要添加其他路由時遇到了問題。我在呈現索引視圖或顯示視圖中的所有操作之後的默認行爲。我的代碼是這樣設置的(大量不相關的代碼被修剪);before_filter在開發和生產模式下的工作方式不同

module RestController extend ActiveSupport::Concern 
    included do 
    before_action: setup_index_view, 
        only: [:index, :new, :create] << @additional_index_routes 
    before_action: setup_show_view, 
        only: [:show, :edit:, update, :destroy] << @additional_show_routes 
    end 

    def setup_rest_controller(_additional_index_routes, 
          _additional_show_routes) 
    @additional_index_routes = _additional_index_routes 
    @additional_show_routes = _additional_show_routes 
    end 

    def setup_index_view 
    # default behavior, sets @{collection_name} = {Model.collection} 
    # code trimmed 
    end 

    def setup_show_view 
    # default behavior, sets @{instance_name} = {Model.find(params[:id]} 
    # code trimmed 
    end 
end 

class Order < ApplicationController 
    def initialize 
    setup_rest_controller(
     _additional_show_routes: [:quote, :contract, invoice_report]) 
    end 

    def setup_index_view 
    #override default behavior to filter andpaginate collection 
    @orders = Orders.active.search(search_terms).paginate 
    end 

    #accept default behavior for setup_views 
end 

在發展中,這段代碼工作正常(我承認我吃驚了一點),但在生產中其他路由沒有運行setup_show_method。 gem文件唯一的區別是開發包含rspec-rails。有誰知道爲什麼這個代碼會有不同的表現?

編輯 只要我打了帖子,'爲什麼'打我。在開發中,代碼在每次請求時重新加載,並且在生產中它只加載一次...在第一次加載@additional_show_routes沒有設置,因此沒有額外的路線被添加到before_action call。新的問題,然後...我如何得到理想的行爲?

OrdersController中添加對before_action的呼叫會覆蓋RestController中的呼叫並打破默認功能。

setup_rest_controller中添加對before_action的調用將引發NoMethodError。

當你添加這樣的問題時,有沒有像new這樣的方法可以用來代替setup_rest_controller來設置@additional_show_views

+0

你確定接管'initialize'方法是'打破默認行爲? –

+0

這是我會立即因爲內在複雜性而恢復的那種代碼。你確定抽象是值得所有這些鬥爭?有沒有辦法在ApplicationController中實現該行爲? – phoet

回答

0

這感覺就像一個黑客,但它似乎得到了預期的結果;

class OrdersController < ApplicationController 

    prepend_before_action Proc.new { send :setup_index_view}, 
     only: [:new_restful_action] 

    def setup_index_view 
    #override default behavior to filter andp aginate collection 
    @orders = Orders.active.search(search_terms).paginate 
    end 

    #accept default behavior for setup_views 
end 

我也滴在RestController@additional_{X}_routes所有引用。我不知道prepend_是在上面寫的代碼中需要的,但在我的實際代碼中還有其他的before_filters需要在@additional_{X}_routes之後運行...

相關問題