Solving ERB Syntax Error in Ruby Dynamic Database Code

I’m trying to output some ruby code stored in my database, specifically from a table named Page that has columns title and content. In the content column, I saved form code. My goal is to render this form in a view. Here’s the code I have:

I created a form with fields for title, price, stock, and image, using form_for :article.

Error Code:

code<%= form_for :article do |f| %>
<div class="form-group">
<%= f.label :title, "Title" %>
<%= f.text_field :title, class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :price, "Price" %>
<%= f.number_field :price, value: 1, class: 'form-control', min: 1 %>
</div>
<div class="form-group">
<%= f.label :stock, "Stock" %>
<%= f.number_field :stock, value: 1, class: 'form-control', min: 1 %>
</div>
<div class="form-group">
<%= f.file_field :image %>
</div>
<%= f.submit "Save", class: 'btn btn-success' %>
<% end %>

In my view, I’m trying to iterate over each page and render the content:

code<% @pages.each do |page| %>
<%= raw ERB.new(page.content).result(binding) %>
<% end %>

However, I keep running into a syntax error:

code(erb):1: syntax error, unexpected ')' t(( form_for :article do |f| ).to_s); _erbout.concat "\r\n<d ^ (erb):22: syntax error, unexpected keyword_end, expecting ')' ; end ; _erbout.force_encoding(__EN ^ (erb):22: syntax error, unexpected end-of-input, expecting ')' t.force_encoding(__ENCODING__) ^

It looks like the error is occurring in ERB processing, but I’m not sure how to resolve it. I suspect it’s related to how form_for is being evaluated within the dynamic ERB template.

Problem Analysis:

The error here is likely caused by attempting to evaluate ERB content (Embedded Ruby) that contains form-related code within another ERB template. When ERB templates contain complex expressions (like form_for), extra care is needed because they use blocks and bindings, which may not be interpreted correctly when re-evaluated.

Solution:

  1. Escape the ERB Block Properly: Since the form code is stored in the database and we are evaluating it dynamically, we should use ERB with raw to render the HTML safely.
  2. Update the ERB Evaluation: Instead of directly evaluating ERB.new(page.content).result(binding), let’s make sure that all ERB code is handled by ERB and safely output using raw to avoid syntax errors.

Revised Code

Here’s the corrected code along with an explanation:

View Code (Rendering the Content)

    code<% @pages.each do |page| %>
    <%= raw ERB.new(page.content).result(binding) %>
    <% end %>

    Content in page.contentEnsure the form content in your page.content column is valid ERB code:

    <%= form_for :article do |f| %>
    <div class="form-group">
    <%= f.label :title, "Title" %>
    <%= f.text_field :title, class: 'form-control' %>
    </div>
    <div class="form-group">
    <%= f.label :price, "Price" %>
    <%= f.number_field :price, value: 1, class: 'form-control', min: 1 %>
    </div>
    <div class="form-group">
    <%= f.label :stock, "Stock" %>
    <%= f.number_field :stock, value: 1, class: 'form-control', min: 1 %>
    </div>
    <div class="form-group">
    <%= f.file_field :image %>
    </div>
    <%= f.submit "Save", class: 'btn btn-success' %>
    <% end %>

      Explanation:

      • ERB.new(page.content).result(binding): This creates a new ERB template based on page.content and evaluates it with the current context (binding). This allows us to dynamically render ERB content stored in the database.
      • raw: Wrapping the ERB.new(page.content).result(binding) in raw ensures that HTML is output directly without escaping, necessary when generating HTML forms or similar content.

      Testing:

      1. Database Content: Make sure that page.content has no syntax issues or partial code blocks. The form code should be fully enclosed in <%= form_for :article do |f| %> ... <% end %>.
      2. Dynamic Rendering: Run this in your application to check if the form renders correctly. If issues persist, verify that page.content doesn’t contain unexpected characters or incomplete ERB code.

      This setup should now properly render the form stored in the database without causing syntax errors.

      Related blog posts