<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>
Why is this producing the following error?
$ 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 ')'
Short version: nothing is wrong; Rails does some crazy stuff.
Long version: You can only do
(that is, use
<%=
with a block) because of a giant flying hack in Rails. The content of<%=
%>
is supposed to be an expression (or expressions) that stands on its own: you should be able to stick it intoeval
and have it be syntactically valid.Before Rails 3, people were sometimes confused by the fact that with ‘normal helpers’ (
link_to
,number_to_currency
, etc.), you had to use<%=
, but when using the block form of these helpers or helpers likeform_for
, you had to use<%
. That’s why Rails 3 made<%=
support blocks.To handle blocks in this case, when you use
<%=
, Rails looks at the ERB code, sees whether it looks like a block by using a regular expression, and if it does rewrites the generated code on the fly to turn it into valid Ruby.More gory details in the excellent blog post “Block Helpers in Rails 3”.
If you look at the code outputted by
erb -x -T - test.erb
:You can see that on the third line, a
do
is followed by a)
. Ruby is expecting ado
…end
block, but gets a closing parenthesis. That’s the immediate cause of the syntax error.The reason for
erb
outtputting bad code is that you are using<%=
when you should be using<%
. Changing your code to this fixes the syntax error:I can’t run this code to test if it outputs what it should after my change, but the code generated by
erb
looks like it will work:Edit
Since this solution apparently does break the output, I looked into what mu is too short suggested. I checked if Erubis, which Rails 3 uses by default, behaves differently from ERB. The code outputted by
erubis -x -T - test.erb
(with the original, uneditedtest.erb
):Line three has the exact same problem, and
erubis -x -T - test.erb | ruby -c
outputs the same syntax error. So the differences between ERB and Erubis are probably not the problem.I also tried syntax-checking this piece of code from the official Rails documentation:
It gets the same syntax error. So it’s not that your ERB code is badly written; your code is very similar to that example.
At this point my best guess is that
erb
’s-x
flag, which translates an ERB template into Ruby code instead of evaluating it directly, is flawed, and does not support some features it should. Though now that I think about it, I am having trouble imagining exactly what Ruby code should be outputted when you output the result of a block that itself outputs text should work. At what times should each of the outputs be written – the result first, or the block contents first?