Как мне 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, который будет старым способом (до того, как вы его переопределите).

Другие вопросы по тегам