before_filter在开发和生产模式下的工作方式不同

时间:2013-12-20 14:03:32

标签: ruby-on-rails ruby-on-rails-4

我正在使用通用控制器为RESTful操作提供默认功能,但是当我需要添加其他路由时遇到问题。我之后的默认行为在索引视图或显示视图中呈现所有操作。我的代码设置如下(许多不相关的代码被修剪);

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。那么新的问题......我如何获得理想的行为?

before_action中添加对OrdersController的调用会覆盖RestController中的before_action,并打破默认功能。

setup_rest_controller中添加对new的调用会抛出NoMethodError。

当您添加这样的问题时,我是否可以使用setup_rest_controller之类的方法而不是@additional_show_views来设置{{1}}?

1 个答案:

答案 0 :(得分: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

我也删除@additional_{X}_routes中对RestController的所有引用。我不知道上面写的代码中需要prepend_,但在我的实际代码中还有其他需要在@additional_{X}_routes之后运行的before_fil ... ...