Rails装饰器方法没有在生产中调用,在开发中工作

时间:2017-06-19 12:42:03

标签: ruby-on-rails ruby spree

我为从gem(Spree)继承的控制器添加以下覆盖:

module Spree
  module Admin
    UsersController.class_eval do
      def index
        if params[:role].present?
          included_users = Spree::User.joins(:role_users).
              where( spree_role_users: { role_id: params[:role] } ).map(&:id)
          flash[:notice] = "Filtered in #{included_users.count} users"
          @users = @users.where(id: included_users)
        end
      end
    end
  end
end

基本上,它通过Admin::UsersController控制器上的附加参数进行过滤。 gem中该控制器的源实际上并没有定义index方法,所以我只是调用它。

现在,这在开发中非常有效。但是,在生产中,这种方法永远不会被调用。

我有没有关于class_eval的某些内容我没有来这里?这样的事情不应该像开发中那样在生产中基本相同吗?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

装饰器是包装另一个对象的对象。例如,它们通常用于包含具有表示逻辑的模型。

class_eval

这不是装饰器方法 - 您只是重新打开类并添加方法。这称为monkey-patching

在这种情况下,使用module Spree module Admin class UsersController def index if params[:role].present? included_users = Spree::User.joins(:role_users). where( spree_role_users: { role_id: params[:role] } ).map(&:id) flash[:notice] = "Filtered in #{included_users.count} users" @users = @users.where(id: included_users) end end end end end 与使用class关键字完全相同:

/app

使用monkey-patches,关键是确保读取类重新定义。我猜测开发和生产之间的区别是由于类捕获,如果已经由Spree gem定义了类,则会阻止从config/application.rb读取类。 config/initializers使用bundler在应用程序启动时需要所有gem。

您可以通过将猴子补丁放入class MyUsersController < ::Spree::Admin::UsersController def index if params[:role].present? included_users = Spree::User.joins(:role_users). where( spree_role_users: { role_id: params[:role] } ).map(&:id) flash[:notice] = "Filtered in #{included_users.count} users" @users = @users.where(id: included_users) end end end 来确保加载猴子补丁,因为该目录中的所有文件都是在启动时加载的。

但是monkeypatching的一个更好的替代方法可能是将供应商控制器和route子类化为它:

var articles= {
    "item1":{
         "id":"155",
         "name":"First Item",
         "value":-5199.6
    },
    "item2":{
         "id":"255",
         "name":"Second Item",
         "value":-424.91
    }
}

var ids = [];
for(var item in articles) {
    ids.push(articles[item]['id']);
}

console.log(ids);

另见: