2012-04-05 3 views
3

약간 이해하기 어려움 alias_method/alias_method_chain입니다. 나는 다음과 같은 코드가 있습니다 :alias_method, alias_method_chain 및 self.included

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_methodalias_method_chain은 구식 솔루션으로, 대신 모듈에 self.included &을 사용해야합니다.

하지만 self.includedform_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) 

위의 솔루션은 작동하지만, 나는 그 일을하는 잘못된 방법이라고 생각합니다. 어떤 루비 참전 용사가 나에게 더 우아한 방법을 보여줄 수 있다면 - 그리고/또는 왜 두 번째 해결책이 호출되지 않는지 - 나는 감사 할 만하다.

+2

두 번째 접근 방식이 작동하지 않는 이유는 다음을 참조하십시오. http://stackoverflow.com/questions/5944278/overriding-method-by-another-defined-in-module – tsherif

+0

많은 도움이되었습니다. 많은 감사합니다 – PlankTon

답변

4

무언가를 패치 할 때 상속 할 수퍼가 없으므로 메소드를 재정의해야합니다 (두 번째 코드 발췌 부분을 사용할 수 없으므로).

현재 메서드 구현을 복사 그냥 문제에 대한 요구하고 당신의 자신의 추가, 그래서 alias_method이 들어오는 곳입니다.

alias_method :form_for_without_cherries, :form_for 

그것은 실제로 당신이 대신 사용할 수있는 원래의 방법에 복제를 생성 감독자. 원숭이 패치를 연결할 수 없다는 사실은 버그가 아니며 기능입니다.

레일스 alias_method_chain 메소드는 실제로는 좋지 않았지만 처음부터 좋지 않았기 때문입니다. 그러나 alias_method는 순수한 루비 메서드이며 올바르게 사용할 경우 원숭이가 코드를 패치하는 우아한 방법을 제공 할 수 있기 때문에 언제든지 곧 사라지지 않을 것이라고 확신합니다.

+0

우수 - 바이스 감사드립니다. – PlankTon

관련 문제