가 가장 일반적으로, 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를 보유하고 있습니다.
댓글에서 귀하의 질문에 레일스는 view
이 ActionView::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은이 모든 것을 설명하는 훌륭한 직업을 수행합니다.
귀하의 설명과 저에게 RailsCast를 알려 주셔서 감사합니다. 나는 여전히 한가지를 이해하지 못한다 : 레일스는'view'가 레일스 뷰의'ActionView :: Base' 뷰 인스턴스라는 것을 어떻게 알 수 있을까요? – davideghz
당신의 업데이트 된 답변은 훌륭 합니다만, ActionView :: Base 인스턴스가 실제로 메소드에 전달 된 링크 된 소스 코드 (라인)의 정확한 라인을 알려주시겠습니까? – davideghz
와우! 나 한테 진짜로 일하게 만들고있어.따라서 참조 된 보석을 면밀히 검사하면 설명서에 ** ** 컨트롤러에서 메타 태그 사용 ** 및 **보기에서 메타 태그 사용 **이 표시됩니다. 이는 PORO 발표자 패턴 (미안)을 따르지 않음을 나타냅니다. 대신 메타 태그 메소드는'meta-tags/lib/meta_tags.rb'의 36 행과 37 행에있는 include 메소드를 통해'ActionController :: Base'와'ActionView :: Base'에 모두 포함되어 있습니다. 이러한 맥락에서,'view'는 항상 사용 가능합니다. – jvillian