2010-02-11 5 views
2

나는 아직도 메타 프로그래밍을 구현하는 방법을 모르겠다.어떻게 메타 프로그래밍을 통해 Ruby on Rails 모듈 메소드를 오버라이드 할 수 있습니까?

내 Admin :: Base 컨트롤러에서 렌더링 된보기의 경우 모든 admin의 레이아웃 파일이 public/admin이되도록 Actionview :: Helpers :: AssetTagHelper 아래에있는 레일 compute_public_path을 덮어 쓰고 싶습니다.

아마도이 방법을 사용하는 것이 좋지만이 시점에서이 방법을 배우는 방법을 배우고 싶습니다.

나는 :: 관리자에서 기본 컨트롤러이를 넣어 :

module ActionView::Helpers::AssetTagHelper 
    def compute_public_path(source, dir, ext = nil, include_host = true) 
    super(source, "admin/#{dir}", ext = nil, include_host = true) 
    end 
end 

를하지만 저를 제공합니다

super: no superclass method `compute_public_path' for #<ActionView::Base:0x1032240a8> 

나를 놀라게하지 않습니다.


내 관리자 도우미에서 이것을 시도하는 경우 : compute_public_path 개인 방법이기 때문에

def compute_public_path_with_admin(source, dir, ext = nil, include_host = true) 
    compute_public_path_without_admin(source, "admin/#{dir}", ext, include_host) 
end 

alias_method_chain :compute_public_path, :admin 

내가 '모듈'AdminHelper '에 대한 정의되지 않은 메서드'compute_public_path '을 "얻을, 나는 추측하고있는 문제가 발생합니다. 그렇지 않으면 내가 스택 레벨 너무 깊이 오류,

ActionView::Helpers::AssetTagHelper.class_eval do 
    def compute_public_path_with_admin(source, dir, ext = nil, include_host = true) 
    compute_public_path_without_admin(source, "admin/#{dir}", ext, include_host) 
    end 

    alias_method_chain :compute_public_path, :admin 
end 

을 한 내가 falseconfig.cache_classes을 설정 한 :

나는이 작품을 발견.

올바른 방향으로 나를 가리키며 Squeegy에게 감사드립니다.

클래스 캐싱을 사용하지 않도록 설정하려면 어떻게해야합니까?

답변

1
def compute_public_path_with_admin(source, dir, ext = nil, include_host = true) 
    compute_public_path_without_admin(source, "admin/#{dir}", ext, include_host) 
end 

alias_method_chain :compute_public_path, :admin 

compute_public_path 이제 구현을 호출하여 원래 구현을 호출합니다.

은 참조 : Is alias_method_chain synonymous with alias_method?

+0

하지만이 코드는 어디에 두어야합니까? 컨트롤러 나 이니셜 라이저에 들어 있습니까? – ToreyHeinz

+0

재정의하려는 메소드가있는 클래스 또는 모듈을 배치하십시오. 모든 관리자보기가 공통으로 공유하는 도우미처럼? 실제로이 메소드가 호출되는 곳이 아니므로 약간 놀아야 할 수도 있습니다. –

+0

메소드가 비공개 인 경우 어떻게됩니까? 나는 그것을 무시하는 것처럼 보일 수 없다. – ToreyHeinz

0

이 작업을 수행하지 마십시오.

허용되는 대답은 원하는 것을 얻을 수 있지만 원하는 것은 위험한 보안 관련 사항 일 수 있습니다.

왜 관리자 레이아웃을 public 아래에 넣으시겠습니까? Rails가 기본적으로 이들을 app/views/layouts에 넣는 데는 이유가 있습니다. 아무도 그 곳에서 소스를 읽을 수 없습니다.

public에 입력하면 기본적으로 모든 방문자가 읽을 수 있습니다.

그들이 속한 곳에 배치하면 레이아웃 코드가 노출되지 않습니다. 그리고 그 위에, app/views/layouts 구조 수 있습니다 어떤 metaprogramming없이 원하는 방식으로, 즉 프레임 워크 내부 해킹하지 않고.

관련 문제