Как мне alias_method с ActiveSupport::Concern?
Я пытаюсь свернуть свое собственное архивирование в рельсы, но мне сложно понять, как создать псевдоним старого destroy
метод, прежде чем переопределить его. Ниже то, что я хотел бы сделать, но я получаю NoMethodError
так как destroy
не определено до этого в модуле. Это работает так, как я ожидал, если бы InstanceMethods
модуль, но это, кажется, устарело. Должен ли я просто справиться с этим с ванильным модулем или есть способ сделать это с ActiveSupport::Concern
?
module Trashable
extend ActiveSupport::Concern
included do
default_scope where(deleted_at: nil)
end
module ClassMethods
def deleted
self.unscoped.where(self.arel_table[:deleted_at].not_eq(nil))
end
end
alias_method :destroy!, :destroy
def destroy
run_callbacks(:destroy) do
update_column(:deleted_at, Time.now)
end
end
end
1 ответ
Вы смешиваете пару вещей.
1 - уничтожение действительно не существует в классе, в который вы включаете свой модуль, прежде чем включить свой модуль.
Длинная история состоит в том, что метод destroy, вероятно, генерируется и включается для вас вашим гемом ORM.
Вы можете использовать ruby 2+ prepend, чтобы убедиться, что ваш модуль появляется после всех методов.
2 - Вы можете использовать ванильный модуль или ActiveSupport::Concern
до тех пор, пока вы получаете то, что хотите, и знаете, что делаете.
Точка ActiveSupport::Concern
в основном для управления иерархиями модулей. Если у вас есть один уровень, я не вижу смысла в его использовании. Думаю смешивать prepend
с ActiveSupport::Concern
не очень хорошая идея
(И в конце концов, ActiveSupport::Concern
это просто ванильные модули в конце концов.)
3 - Рекомендуемый способ переопределить метод при сохранении старого - использовать alias_method_chain.
После этого у вас будет доступный метод destroy_without_archive, который будет старым способом (до того, как вы его переопределите).