2012-01-24 2 views
1

나는 한 쌍의 레일즈 헬퍼를 가지고 있는데, 그 중 하나는 블록을 받아 들일 것이고 다른 하나는 버튼을 렌더링하는 것이다. 여기에 단순화 된 버전은 도우미의 정의입니다 :Ruby 블록에서 여러 문장의 결과를 얻으려면 어떻게해야합니까?

def nav_wrapper(nav_at, id, css_class, &block) 
    "<ul class="complicated">\n #{yield} \n</ul>".html_safe 
end 

def nav_btn(nav_at, caption, id = caption.downcase.dasherize) 
    "Nav button codes goes here".html_safe 
end 

I가 내가 이런 식으로 뭔가 할 수있는 그런 일을 설정하기 위해 노력하고있어 :

<%= nav_wrapper(@nav_at, "Top Nav", "class") do %> 
    <%= nav_btn(@nav_at, "Foo", "id") %> 
    <%= nav_btn(@nav_at, "Bar", "id") %> 
    <%= nav_wrapper(@nav_at, "Sub Nav", "class") do %> 
    <%= nav_btn(@nav_at, "SubFoo", "id") %> 
    <%= nav_btn(@nav_at, "SubBar", "id") %> 
    <% end %> 
<% end %> 

을 단, nav_wrapper 방법에 yield 만 집어 들고 각 블록의 마지막 문장. 그래서이 예제에서, Top Nav 래퍼 인 Foo와 Bar를 건너 뛰고 Sub Nav 래퍼 (바깥 쪽의 마지막 문인 nav_wrapper 블록)를 얻습니다. SubFoo는 건너 뛰고 SubBar를 얻습니다. 내부는 nav_wrapper 블록).

이 동작의 이유는 코드 블록이 최종 평가 값을 암시 적으로 반환한다는 것이지만 모든 틈새 라인 (예 : form_for)을 렌더링하는 많은 템플릿 도우미가 있음을 알고 있습니다. 누군가 마술 트릭이 여기에 무엇인지 알아낼 수 있습니까?

답변

3

ERB 템플릿을 컴파일 할 때 문자열을 버퍼에 추가하는 코드로 변환됩니다. (무슨 뜻인지 알기 위해 ERB의 소스 코드를 보라.) Action from Action from form_for과 같은 뷰는 블록을 실행 한 다음 ERB 버퍼의 텍스트를 검색한다.

lib/ruby/1.9.1/gems/1.9.1 폴더를 열고 actionpack을 찾으십시오. 가지고있는 액션 팩 버전을 열고 lib/action_view/helpers/capture_helper.rb으로 가십시오. 그곳에는 capture이라는 메서드가 있는데, 이는 form_for이 블록을 실행하고 ERB에 의해 생성 된 텍스트를 검색하는 데 사용됩니다.

레일 도우미를 작성하는 경우 아마도 코드에 capture을 사용할 수 있습니다. 그렇지 않은 경우 include ActionView::Helpers::CaptureHelper을 시도하십시오.

+2

나는 그것을 테스트했습니다! @Alex가'yield '를'capture (& block)'로 대체해야한다는 말을 다시 시작합니다. – fguillen

+1

그건 속임수 였어. 내'nav_wrapper' 메소드의 맨 위에'body = capture (& block)'줄을 추가하고'yield'를'body'로 대체했습니다. 엄청 고마워! –

관련 문제