2016-09-12 8 views
2

Когда я устанавливаю патч обезьяны ActiveRecord :: Base с помощью методов класса, методы наследуются различными классами класса ActiveRecord_Relation (например, User :: ActiveRecord_Relation) и могут быть вызваны экземплярами конкретных активных отношений записи. Но это вызывает некоторое неожиданное поведение при совершении активных вызовов записи для исходной модели.Почему методы перехвата обезьян на ActiveRecord :: Base переопределяют несвязанные методы на Model.count

Вот тривиальный пример:

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 

Что вызывает такое поведение?

Я знаю, что исправление обезьяны, как будто это довольно плохая идея для чего-то серьезного. Я случайно обнаружил это поведение, и мне очень любопытно узнать, почему это происходит.

+0

Что вы хотите сказать? –

+0

Я думаю, вопрос в том, что происходит с 'users.monkey_foo' –

+0

Да. Я могу отредактировать вопрос, чтобы сделать это более ясным. –

ответ

1

Ключ к этому вопросу в delegation.rb

В основном это метод последующей реализации не хватает для соотношения (упрощено немного для краткости)

def method_missing(method,*args,&block) 
    scoping { @klass.public_send(method, *args, &block) } 
end 

(@klass является активная запись Класс отношение принадлежит)

Метод определения области определяет класс 'current_scope на время действия блока. Это содержит такие вещи, как where clauses, sorts и т. Д. Это позволяет вам вызывать методы класса в отношениях и использовать эти методы класса в области, определяемой этим отношением.

В книжном чехле это все еще происходит, однако область видимости происходит с книгой, но запрос против пользователя, поэтому область обзора не изменяет результат.

+0

Спасибо, это очень интересно и полезно. Смешно, что это лучший способ реализовать это поведение, кажется, очень тяжело. –

 Смежные вопросы

  • Нет связанных вопросов^_^