Кажется, что alias_method не работает одинаково внутри класса < < самоблокируется, как и снаружи. В частности, когда я использую alias_method для метода экземпляра и впоследствии переопределяю метод, имя псевдонима можно использовать для доступа к исходному методу. Однако я не могу это сделать с помощью метода класса.ruby alias_method в методе класса
Это мой прецедент: Я переопределяю методы destroy и destroy, которые унаследованы от базы ActiveRecord, потому что код, написанный в настоящее время, позволяет легко удалять строки, когда вы хотели удалить записи объединений. Этот проект может измениться с помощью более крупного проекта, но пока это мое решение по большей части, никто никогда не захочет удалять строки из этой таблицы. Но для того, чтобы допустить преднамеренное удаление строк в таблице для благих намерений, я использую alias_method, чтобы сохранить дескриптор исходных методов destroy и destroy_all. Используя псевдоним работает, чтобы получить доступ к исходному: метод уничтожения (например), но не позволяет мне получить доступ к исходному: desotry_all метод (класс)
class HoldReason < ActiveRecord::Base
class << self
alias_method :remove_hold_reasons_from_table, :destroy_all
def destroy_all
raise "Nope"
end
end
alias_method :remove_hold_reason, :destroy
def destroy
raise "Nope"
end
end
Здесь мы видим, что в то время как эта стратегия работает для экземпляра метод, чтобы позволить успешное удаление одной строки:
> HoldReason.find_by(title: "Management Review").remove_hold_reason
HoldReason Load (0.7ms) SELECT `hold_reasons`.* FROM `hold_reasons` WHERE `hold_reasons`.`title` = 'Management Review' LIMIT 1
(0.5ms) BEGIN
SQL (4.6ms) DELETE FROM `hold_reasons` WHERE `hold_reasons`.`id` = 23
(0.6ms) COMMIT
=> #<HoldReason id: 23, title: "Management Review", category: "Operations">
Я не в состоянии получить доступ к оригиналу: метод destroy_all удалить несколько строк в одном запросе; вместо этого, я получаю перекрытый метод, даже если я использую псевдоним:
> HoldReason.remove_hold_reasons_from_table
HoldReason Load (0.7ms) SELECT `hold_reasons`.* FROM `hold_reasons`
RuntimeError: Nope
Что происходит, что я не могу сделать это для методов класса, и как я могу это исправить (кроме просто использовать необработанный SQL-запрос для удаления)?
Ваш вопрос остается неясным. Выделенный фрагмент кода ясно показывает, что 'alias_method' * does * работает: в противном случае вы получите' NoMethodError'. –
Я отредактировал вопрос. Намерение заключается в том, что использование имени псевдонима дает мне доступ к исходному методу, прежде чем он будет переопределен, чтобы вызвать ошибку. Это то, что работает, например, методы, но не методы класса; в случае метода класса псевдоним по-прежнему использует переопределенный метод, тогда как в случае метода экземпляра я получаю доступ к исходному, не переопределенному методу, когда я использую псевдоним. –
Извините, я до сих пор не понимаю. В обоих случаях вы можете вызвать метод под его псевдонимом. Итак, 'alias_method' работает в обоих случаях. Между этими двумя случаями нет разницы. В классе 'Module' существует ровно * одна реализация' alias_method', и она работает точно так же для * all * modules, будь то * актуальные * модули, классы или одноэлементные классы. 'alias_method' делает одно и только одно: скопируйте метод под новым именем. Период. И это работает, о чем свидетельствует тот факт, что вы не получаете «NoMethodError». –