Почему это ошибка с ERB?
<div class='row'>
<%= form.field_container :name do %>
<%= form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) %>
<%= form.text_field :name, :class => 'fullwidth' %>
<%= form.error_message_on :name %>
<% end %>
</div>
почему это приводит к следующей ошибке?
$ erb -x -T - test.erb | ruby -c
-:3: syntax error, unexpected ')'
...form.field_container :name do ).to_s); _erbout.concat "n"
... ^
-:9: syntax error, unexpected $end, expecting ')'
2 ответов
если вы посмотрите на код, выдаваемых erb -x -T - test.erb
:
#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n "
; _erbout.concat(( form.field_container :name do ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.text_field :name, :class => 'fullwidth' ).to_s); _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.error_message_on :name ).to_s); _erbout.concat "\n"
; _erbout.concat " "; end ; _erbout.concat "\n"
; _erbout.concat "</div>\n"
; _erbout.force_encoding(__ENCODING__)
вы можете видеть, что на третьей строке, a do
после )
. Руби ожидает do
...end
блок, но получает закрывающую скобку. Это непосредственная причина ошибки.
причина erb
outtputting плохой код, что вы используете <%=
когда вы должны использовать <%
. Изменение кода на this исправляет синтаксис ошибка:
<div class='row'>
<% form.field_container :name do %>
<%= form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) %>
<%= form.text_field :name, :class => 'fullwidth' %>
<%= form.error_message_on :name %>
<% end %>
</div>
Я не могу запустить этот код, чтобы проверить, выводит ли он то, что он должен после моего изменения, но код, сгенерированный erb
похоже, это будет работать:
#coding:ASCII-8BIT
_erbout = ''; _erbout.concat "<div class='row'>\n "
; form.field_container :name do ; _erbout.concat "\n"
; _erbout.concat " "; _erbout.concat(( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s); _erbout.concat "\n"
# more...
редактировать
так как это решение, по-видимому тут сломайте выход, я посмотрел, что mu слишком короткий предложил. Я проверил, если erubis аппликации, который Rails 3 используется по умолчанию, ведет себя иначе, чем ERB. Выведенный код by erubis -x -T - test.erb
(с оригинальной, неотредактированной test.erb
):
_buf = ''; _buf << '<div class=\'row\'>
'; _buf << ( form.field_container :name do ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.label :name, raw('Name' + content_tag(:span, ' *', :class => 'required')) ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.text_field :name, :class => 'fullwidth' ).to_s; _buf << '
'; _buf << ' '; _buf << ( form.error_message_on :name ).to_s; _buf << '
'; end
_buf << '</div>
';
_buf.to_s
Третья строка имеет точно такую же проблему, и erubis -x -T - test.erb | ruby -c
выводит ту же ошибку синтаксиса. Таким образом, различия между ERB и Erubis, вероятно, не являются проблемой.
Я также попробовал синтаксис-проверка этого фрагмента кода из официальной документации Rails:
<%= form_for(zone) do |f| %>
<p>
<b>Zone name</b><br />
<%= f.text_field :name %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
он получает ту же ошибку синтаксиса. Так что дело не в том, что ваш код ERB плохо написан; ваш код очень похож к этому примеру.
на данный момент мое лучшее предположение, что erb
' s -x
флаг, который переводит шаблон ERB в код Ruby вместо того, чтобы оценивать его напрямую, имеет недостатки и не поддерживает некоторые функции, которые он должен. Хотя теперь, когда я думаю об этом, мне трудно представить, что именно Ruby code должны выводится при выводе результата блока, который сам выводит текст должен работать. В какое время должен быть записан каждый из выходов – сначала результат или содержимое блока?
короткая версия: ничего не случилось; Rails делает некоторые сумасшедшие вещи.
длинная версия: вы можете только сделать
<%= some_method do %>
<% end %>
(то есть, использовать <%=
С блоком) из-за гигантского летающего взлома в рельсах. Содержание <%=
%>
предполагается, что это выражение (или выражения), которое стоит само по себе: вы должны быть в состоянии вставить его в eval
и это будет синтаксически правильным.
перед рельсами 3, Люди иногда были смущены тем фактом, что с "нормальными помощниками" (link_to
, number_to_currency
, etc.), вы должны использовать <%=
, но при использовании блочной формы этих помощников или помощников, таких как form_for
, вы должны использовать <%
. Вот почему Rails 3 сделал <%=
поддержка блоков.
для обработки блоков в этом случае, когда вы используете <%=
, Rails смотрит на код ERB, видит, выглядит ли он как блок с помощью регулярного выражения, и если он переписывает сгенерированный код на лету, чтобы превратить его в действительный Ruby.
больше кровавые подробности в отличном блоге"блок помощников в Rails 3".