Переопределить метод поиска CollectionProxy - PullRequest
0 голосов
/ 02 ноября 2018

Как правильно переопределить ActiveRecord find, чтобы он вел себя одинаково при использовании в классе модели (например, Comment.find(1)) и коллекции (например, post.comments.find(1))?

Давайте возьмем эти две простые модели в качестве примера:

class Post < ApplicationRecord
  has_many :comments
end

class Comment < ApplicationRecord
  belongs_to :post

  def self.find(*args)
    puts 'Overridden find called!'
    super
  end
end

С такими классами Comment.find(1) правильно использует переопределенный метод, но post.comments.find(1) все еще использует оригинальную версию find. Я знаю, что могу переопределить #find в ActiveRecord::Associations::CollectionProxy, но мне не нравится это решение, потому что оно влияет на каждую модель в приложении. Не могли бы вы предложить правильное решение?

EDIT: Чего я хочу добиться:

Comment.find(1) # prints 'Overridden find called'
some_post.comments.find(1) # prints 'Overridden find called'
Post.find(1) # does NOT print 'Overridden find called', calls regular find

1 Ответ

0 голосов
/ 02 ноября 2018

Поскольку CollectionProxy вызывает find на CollectionAssociation, что впоследствии вызывает scope.find, вам не нужно делать что-то необычное для переопределения:

module CustomFinder
  def find
    puts "I'm noisy!"
    super
  end
end

class Post < ApplicationRecord
  extend CustomFinder
  has_many :comments
end

class Comment < ApplicationRecord
  extend CustomFinder
  belongs_to :post
end

В качестве альтернативы, если вы делаете хотите это для каждой модели:

class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true
  extend CustomFinder
end

В будущем вы можете использовать foo.method(:find).source_location, а затем просмотреть соответствующий код на Github, чтобы лучше понять, что происходит под капотом, не тратя много времени на темное времяпровождение в темноте.

В качестве другого примера того, как это сделать, проверьте, как с этим справляется Friendly ID .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...