alias_method, alias_method_chain и self.included
У меня есть небольшие трудности с пониманием alias_method
/alias_method_chain
, У меня есть следующий код:
module ActionView::Helpers
module FormHelper
alias_method :form_for_without_cherries, :form_for
def form_for(record, options = {}, &proc)
output = 'with a cherry on top'.html_safe
output.safe_concat form_for_without_cherries(record, options = {}, &proc)
end
end
end
Это делает именно то, что я хочу - добавить "с вишенкой на вершине" к вершине любого form_for
вызов.
Но я понимаю, что это не очень хороший код по нескольким причинам. Во-первых, он не будет цепляться в любых других переопределениях form_for(?)
так что если бы я написал вторую form_for
метод, который добавлен "и еще одна вишня сверху", это не показывало бы. И во-вторых, alias_method
а также alias_method_chain
Сорта устарели решения, и я должен использовать self.included
и отправка в модуль вместо.
Но я не могу получить self.included
называть это form_for
метод - он просто продолжает вызывать родительский. Вот что я пытаюсь:
module CherryForm
def self.included(base)
base.extend(self)
end
def form_for(record, options = {}, &proc)
output = 'with a cherry on top'.html_safe
output.safe_concat super(record, options = {}, &proc)
end
end
ActionView::Helpers::FormHelper.send(:include, CherryForm)
Мое вышеупомянутое решение работает, но у меня есть подозрение, что это неправильный способ действий. Если бы какие-нибудь ветераны рубина могли показать мне более изящный способ сделать это - и / или почему второе решение не вызывается - я был бы благодарен.
1 ответ
Когда вы что-то исправляете, вы должны переопределить метод, потому что нет супер-объекта для наследования (поэтому вы не можете использовать второй фрагмент кода).
Копирование текущей реализации метода и добавление вашей собственной просто вызывает проблемы, так что здесь вступает alias_method.
alias_method :form_for_without_cherries, :form_for
Это фактически создает клон к оригинальному методу, который вы можете использовать вместо super. Тот факт, что вы не можете связать патчи обезьяны, это не ошибка, это особенность.
Метод rails alias_method_chain действительно устарел, но только потому, что с самого начала это была плохая идея. Тем не менее, alias_method - это чистый метод ruby, и при правильном использовании он может обеспечить элегантный способ обезопасить ваш код, поэтому я уверен, что он не исчезнет в ближайшее время.