2016-08-03 1 views
0

소스 코드 this gem을 탐색 중이었고 content_tag를 사용하여 많은 것을 혼란스럽게 보았습니다.레일스 content_tag 메소드

def render(view) 
    view.content_tag(name, attributes[:content], attributes.except(:content)) 
end 

왜 content_tag가 뷰에서 호출되는지 이해할 수 없습니다. 저는 HTML 태그를 생성하는 데 일반적으로 도우미로 사용하지만, 메서드로 호출 한 적이 없습니다.

답변

2

가 가장 일반적으로, content_tag이 뷰의 컨텍스트에서 호출되는 - 그래서, 당신이보기 content_tag에 응답하는 방법을 알고 있기 때문에 view.content_tag를 호출 할 필요는 없다 (단순히 content_tag를 호출하면 self.content_tag를 호출 한 것과 같은 상태가된다).

표시되는 render 메서드는 Tag에서 상속하는 MetaTag 클래스 내에 있습니다. Tag은 일반 오래된 Ruby 객체 (PORO)이므로 content_tag에 응답하는 방법을 알지 못합니다.

그러나 알다시피, render 메서드는보기를 인수로 취합니다. 그리고 당연히 view 개체는 content_tag에 응답하는 방법을 알고 있습니다. 따라서 view.content_tag을 호출하면 MetaTag이 콘텐츠 태그를 렌더링 할 수 있습니다.

이것은 많은 발표자 패턴의 인스턴스입니다 (다른 사람들은 다른 용어를 사용함). Ryan Bates는이 here에 대한 좋은 RailsCast를 보유하고 있습니다.

댓글에서 귀하의 질문에 레일스는 viewActionView::Base의 인스턴스라는 것을 "알지 못합니다". 실제 뷰 인스턴스를 전달할 책임이 있습니다. 컨트롤러에 전달하여보기 및 매개 변수에 액세스 할 수 있습니다. 이 같은 아마 뭔가 :

class FooController < ApplicationController 

    def foo_action 
    FooPresenter.present(self) 
    end 

end 

및 ...

class FooPresenter 
    class << self 

    def present(controller) 
     new(controller).present 
    end 

    end # class methods 

    #=================================================================== 
    # instance methods 
    #=================================================================== 

    def initialize(controller) 
     @controller = controller 
    end 

    def present 
     content_tag :div, data: {foo: params[:foo]}, class: 'bar' 
    end 

    private 

    def controller() @controller    end 
    def view()  controller.view_context end 
    def params()  controller.params   end 

    def method_missing(*args, &block) 
     view.send(*args, &block) 
    end 

end 

method_missing 방법을 포함함으로써, 나는 더 이상 view.content_tag를 호출 할 필요가 없습니다. content_tag으로 전화하면됩니다. FooPresenter는 메소드를 찾지 못하기 때문에 메소드가 발견되어 실행될 view에 호출을 보냅니다.

다시 Ryan은이 모든 것을 설명하는 훌륭한 직업을 수행합니다.

+0

귀하의 설명과 저에게 RailsCast를 알려 주셔서 감사합니다. 나는 여전히 한가지를 이해하지 못한다 : 레일스는'view'가 레일스 뷰의'ActionView :: Base' 뷰 인스턴스라는 것을 어떻게 알 수 있을까요? – davideghz

+0

당신의 업데이트 된 답변은 훌륭 합니다만, ActionView :: Base 인스턴스가 실제로 메소드에 전달 된 링크 된 소스 코드 (라인)의 정확한 라인을 알려주시겠습니까? – davideghz

+1

와우! 나 한테 진짜로 일하게 만들고있어.따라서 참조 된 보석을 면밀히 검사하면 설명서에 ** ** 컨트롤러에서 메타 태그 사용 ** 및 **보기에서 메타 태그 사용 **이 표시됩니다. 이는 PORO 발표자 패턴 (미안)을 따르지 않음을 나타냅니다. 대신 메타 태그 메소드는'meta-tags/lib/meta_tags.rb'의 36 행과 37 행에있는 include 메소드를 통해'ActionController :: Base'와'ActionView :: Base'에 모두 포함되어 있습니다. 이러한 맥락에서,'view'는 항상 사용 가능합니다. – jvillian

1

content_tag은 너무 많은 세부 사항을 언급하지 않고 ActionView::Helpers::TagHelper 클래스의 메소드입니다. 나는이 클래스의 객체가 자동으로 레일스 뷰에 포함되거나 레일스 뷰 객체 델리게이트가이 객체에 포함된다고 생각한다. 상기 방법은 ActionView::Helpers::TagHelper의 일부 content_tag 방법에 대한 액세스를 갖도록

이 특정 일품 render 그 메소드의 파라미터로서 ActionView::Base 객체 걸린다. 이것은 객체 지향 프로그래밍의 기본 원칙 인 Dependency Injection의 예입니다.

관련 문제