首页 > 解决方案 > 如何猴子补丁 ActiveRecord::QueryMethods?

问题描述

我正在尝试修补一种方法,在ActiveRecord::QueryMethods该方法上增加 select 子句,而不是完全替换它。

我试过了:

# config/initalizers/select_also.rb
module SelectAlso
  def select_also(*fields)
    select(self.select_values + fields)
  end
end

ActiveRecord::QueryMethods.include(SelectAlso)

但这给了我:

/lib/ruby/gems/2.6.0/gems/bootsnap-1.4.5/lib/bootsnap/load_path_cache/core_ext/active_support.rb:79:in `block in load_missing_constant': uninitialized constant ActiveRecord::Relation::QueryMethods (NameError)

ActiveRecord::Relation::QueryMethods因为我没有引用它,所以我根本不知道它从哪里得到常量。

我将其作为猴子补丁进行操作的原因是,我想将其作为对 rails 本身的潜在 PR / 功能请求进行尝试,而无需处理 rails 源代码并处理设置示例应用程序。

用例是您想要添加聚合或连接列等内容而不重新创建整个 select 子句的地方:

User.joins(:answers)
   .select_also('AVG(answers.score) AS average_score')

代替:

User.joins(:answers)
   .select('users.*','AVG(answers.score) AS average_score')

或者一些在桌面上自省的 hacky 解决方案。

标签: ruby-on-rails

解决方案


您可能需要考虑ActiveRecord::QueryMethods#extending作为猴子修补的替代方案 - 它旨在通过其他方法扩展范围。

module Pagination
  def page(number)
    # pagination code goes here
  end
end

scope = Model.all.extending(Pagination)
scope.page(params[:page])

Rails 还支持对关联应用扩展,这非常简洁。


推荐阅读