Rails + Haml: возвращение из частичного будет каким-то образом удалять тег формы - PullRequest
1 голос
/ 05 марта 2010

Это долго, да, я прошу прощения. Но я хочу быть ясным, потому что эта проблема очень странная.

У меня есть модальное соглашение об условиях обслуживания, которое возникает, когда пользователь не принимает наши условия обслуживания (TOS). Для целей здесь javascript отключен, и то, что отображается, строго html / css. Таким образом, страница, если рассматривать ее в 3 слоях, это: нижний слой = страница, которую они увидели (т. Е. Страница события), средний слой: полупрозрачное наложение, верхний (основной / видимый) слой: модальное с терминами формы договора об обслуживании в нем. Эта форма является просто флажком принять и отправить кнопку.

Я заметил, что TOS не работал должным образом, но, казалось бы, в случайное время. Затем я заметил, что он был сломан, но только на моей странице событий (/ event / foo), хотя тот же самый фрагмент отвечает за показ условий соглашения об обслуживании, независимо от того, где они отображаются на сайте. Так что для любой другой страницы, например / group / bar, тот же мод TOS будет отображаться и будет работать нормально.

Затем я понял, что проблема была в том, что в моем HTML отсутствовал тег формы! Просто ушел.

Итак, сделав шаг назад, рассматриваемый код (HAML) просто:

%div#accept_tosC
  %b Before form_for
  - form_for @current_user do |form|
    %b After form_for
    %div#tosC= render :partial => 'general/terms'

    %div.left
      = render :partial => 'shared/user/tos_form_element'
    %div.right
      = image_submit_tag "/images/buttons/submit_100x20.png", :id => 'submit', :name => 'submit'

Для нашей страницы / events / foo сгенерированный HTML-код выглядит следующим образом:

<div id="accept_tosC">
   <b>before form_for</b>
  <div style="margin: 0pt; padding: 0pt;"><input type="hidden" value="put" name="_method"><input type="hidden" value="44c2bf7a64fc59baa3fc7129167f0e2c3e96abb6" name="authenticity_token"></div>
      <b>after form_for</b>

Очевидный вопрос здесь заключается в том, что, если 'Before form_for' и 'After form_for' попадают в документ, почему тег формы form_for не создает?

Для другой страницы, скажем / groups / foo, мы получаем именно то, что ожидаем:

<div id="accept_tosC">
  <b>before form_for</b>
  <form method="post" id="edit_user_595" class="edit_user" action="/users/595"><div style="margin: 0pt; padding: 0pt;"><input type="hidden" value="put" name="_method"><input type="hidden" value="44c2bf7a64fc59baa3fc7129167f0e2c3e96abb6" name="authenticity_token"></div>
    <b>after form_for</b>

Я проследил это до одной частичной лунки внутри кода для «нижнего» слоя (страницы, которую они запрашивали, а не наложения TOS). Этот частичный вопрос может или не может быть видим для любого конкретного человека, поэтому мы должны проверить, может ли пользователь просматривать эту страницу. Результат этого содержится в переменной can_view:

:ruby
  #some processing to set page info and can_view
  return unless can_view

%div#statsC
  ...and so on...

Вот так выглядел мой код, а тег формы не рендерится. После внесения следующего изменения тег элемента формы отобразился ожидаемым образом для всех страниц:

:ruby
  #some processing to set page info and can_view

- if can_view
  %div#statsC
    ...and so on...

Итак, вот вопрос: почему возвращение из частичного препятствует тому, чтобы тег элемента формы стал частью документа?

1 Ответ

2 голосов
/ 05 марта 2010

Короткий ответ: шаблоны работают загадочным образом, и return, как правило, небезопасно использовать в них.

Длинный ответ заключается в том, что за кулисами шаблоны компилируются в методы Ruby, которые создают строку HTML-кода и возвращают этот код. Я предполагаю, что, возвращая без возврата правильного кода, вы заставляете что-то идти наперекосяк и отбрасывать строку, к которой form_for присоединяется.

...