Ruby on rails 为什么ActiveRecord::Base上的monkey补丁方法在Model.count上重新定义了不相关的方法

Ruby on rails 为什么ActiveRecord::Base上的monkey补丁方法在Model.count上重新定义了不相关的方法,ruby-on-rails,activerecord,monkeypatching,Ruby On Rails,Activerecord,Monkeypatching,当我使用类方法修补ActiveRecord::Base时,这些方法由不同的模型ActiveRecord_关系类(如User::ActiveRecord_关系)继承,并且可以在特定活动记录关系的实例上调用。但是,在对原始模型进行活动记录调用时,这会导致一些意外行为 下面是一个简单的例子: User.count => 3544 users = User.where("created_at > ?", 1.month.ago) users.count => 174 class A

当我使用类方法修补ActiveRecord::Base时,这些方法由不同的模型ActiveRecord_关系类(如User::ActiveRecord_关系)继承,并且可以在特定活动记录关系的实例上调用。但是,在对原始模型进行活动记录调用时,这会导致一些意外行为

下面是一个简单的例子:

User.count
=> 3544

users = User.where("created_at > ?", 1.month.ago)
users.count
=> 174

class ActiveRecord::Base
    def self.monkey_foo(options = {}, &block)
        User.count
    end
end

User.monkey_foo
=> 3544

Book.monkey_foo # Another model
=> 3544

users.monkey_foo
=> 173 # This is the count of the users relation, not the User model

Book.where("created_at > 1.year.ago").monkey_foo
=> 3544 # Issue only affects User model relations
是什么导致了这种行为


我知道,像这样的猴子修补是一个非常坏的主意,任何严重的事情。我无意中发现了这种行为,我很好奇为什么会发生这种情况。

这个问题的关键是delegation.rb

基本上,这种方法缺少关系的实现(为简洁起见稍微简化)

(@klass是关系所属的活动记录类)

作用域方法为块的持续时间设置类“
current\u scope
。它包含where子句、sorts等内容。这允许您对关系调用类方法,并让这些类方法在关系定义的范围内操作


在book案例中,这种情况仍在发生,但是范围正在book上发生,但是查询是针对用户的,因此范围不会改变结果。

你的问题是什么?我认为问题是,用户发生了什么。monkey_foo是的。我可以修改这个问题使它更清楚。谢谢,这很有趣,也很有帮助。有趣的是,这是实施这种行为的最佳方式,似乎非常严厉。
def method_missing(method,*args,&block)
  scoping { @klass.public_send(method, *args, &block) }
end