Ruby on rails Rails装饰器方法未在生产中调用,正在开发中工作

Ruby on rails Rails装饰器方法未在生产中调用,正在开发中工作,ruby-on-rails,ruby,spree,Ruby On Rails,Ruby,Spree,我为从gem(Spree)继承的控制器添加以下覆盖: 基本上,它通过Admin::userscocontroller控制器上的附加参数进行过滤。gem中该控制器的源代码实际上没有定义index方法,因此只调用了我的方法 现在,这在开发中非常有效。但是,在生产环境中,此方法从未被调用 关于class\u eval有什么我不知道的吗?像这样的工作在生产中不应该和在开发中基本相同吗 谢谢您的帮助。装饰器是包装另一个对象的对象。例如,它们通常用于用表示逻辑包装模型 class UserDecorator

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

基本上,它通过
Admin::userscocontroller
控制器上的附加参数进行过滤。gem中该控制器的源代码实际上没有定义
index
方法,因此只调用了我的方法

现在,这在开发中非常有效。但是,在生产环境中,此方法从未被调用

关于
class\u eval
有什么我不知道的吗?像这样的工作在生产中不应该和在开发中基本相同吗


谢谢您的帮助。

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

class UserDecorator < SimpleDelegator
  def full_name
    "#{first_name} #{last_name}"
  end
end

> @user = UserDecorator.new(User.new(first_name: 'John', last_name: 'Doe'))
> @user.full_name
=> "John Doe"
使用monkey补丁的关键是确保您的类重新定义是可读的。我猜开发和生产之间的区别在于类捕获,如果spreegem已经定义了类,那么类捕获会阻止类从
/app
读取
config/application.rb
使用bundler在应用程序启动时要求所有gem

您可以通过将monkey补丁放在
config/initializers
中来确保加载monkey补丁,因为该目录中的所有文件都是在启动时加载的

但monkeypatching的更好替代方案可能是对供应商控制器进行子类化,并将其添加到:

类MyUsersController<::Spree::Admin::UsersController
def索引
如果参数[:角色]。是否存在?
included\u users=Spree::User.joins(:角色\u用户)。
其中(spree_role_用户:{role_id:params[:role]}).map(&:id)
flash[:notice]=“在#{included_users.count}用户中过滤”
@users=@users.where(id:included\u users)
结束
结束
结束
另见:

此代码的文件名是什么?还有,你把它保存在应用程序目录的什么地方了?不小心双重发布了这个答案。谢谢。就是这样。实际上,我习惯于从我自己的文件夹中使用monkey补丁,并使用一个小脚本从initialiser文件夹中加载它。然而,我必须在每次编辑时重新启动应用程序。我想这是对便利性的惩罚。是的,使用子类在很多方面是一个更干净的解决方案,可以避免加载问题。在运行时修改供应商代码应该是最后的选择。
class UserDecorator < SimpleDelegator
  def full_name
    "#{first_name} #{last_name}"
  end
end

> @user = UserDecorator.new(User.new(first_name: 'John', last_name: 'Doe'))
> @user.full_name
=> "John Doe"
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 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