Как получить результаты от нескольких операторов в блоке Ruby? - PullRequest
1 голос
/ 24 января 2012

У меня есть пара помощников Rails, один из которых предназначен для принятия блока, а другой просто рендерит кнопку. Вот упрощенные версии определения помощника:

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

Я пытаюсь настроить все так, чтобы я мог сделать что-то вроде этого:

<%= 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 %>

Но yield в методе nav_wrapper выбирает только последний оператор каждого блока. Таким образом, в этом примере я получаю оболочку Top Nav, Foo и Bar пропускаются, я получаю оболочку Sub Nav (являющуюся последним оператором во внешнем блоке nav_wrapper), SubFoo пропускается, и я получаю SubBar (будучи последним оператор во внутреннем блоке nav_wrapper).

Я знаю, что причина такого поведения в том, что блок кода неявно возвращает последнее оцененное значение, но я знаю, что есть много помощников шаблонов, которые отображают все промежуточные строки (например, form_for). Может ли кто-нибудь помочь мне понять, в чем тут фокус?

1 Ответ

3 голосов
/ 25 января 2012

Когда шаблон ERB компилируется, он преобразуется в код, который добавляет строки в буфер.(Посмотрите на исходный код для ERB, чтобы понять, что я имею в виду.) Методы из Action View, например, form_for выполняют блок, а затем извлекают текст из буфера ERB.

Откройте папку lib/ruby/1.9.1/gems/1.9.1и искать actionpack.Откройте любую версию пакета действий, которая у вас есть, и перейдите на lib/action_view/helpers/capture_helper.rb.Там есть метод с именем capture, который используется form_for для выполнения блока и извлечения текста, сгенерированного ERB.

Если вы пишете помощник по Rails, то, вероятно, capture будетбыть доступным для вашего кода.Если нет, попробуйте include ActionView::Helpers::CaptureHelper.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...