Pass variable from template to view

30 Jun 2010

Maybe I'm missing a code smell but I needed to pass a variable from my template to my view. The template renders a very generic form and I wanted to add a field to it from my view. I wanted the code to look something like this:

  <% render :layout => '/layouts/confirm',
            :locals => { :entity => @voucher } do |f| %>
      <%= f.input :redeemed_by, :label=>"Voucher Used By"  %>
  <% end %>

I'm using formtastic and the |f| coming down the chute is meant to be the formtastic form builder object.

I tried adding a yield to my layout file like this:

  <% semantic_form_for(entity) do |f| %>
    <%= yield f %>
    <% f.buttons do %>
      <%= submit_tag "Confirm" %>
      <%= submit_tag "Cancel", :name => "cancel", :class=>"submit-other" %>
    <% end  %>
  <% end %>

That resulted in this error message:

  `@content_for_#<Formtastic::SemanticFormBuilder:0x10ae6b490>' is not allowed as an instance variable name

So, after about an hour of searching and reading I tried to figure out how to turn the entire layout file into a helper method. That didn't look like something I wanted to do. Then I started, as I said to my boss, "typing in random crap" and found something that worked:

Layout:

  <% semantic_form_for(entity) do |f| %>
    <%= yield :ignore, f %>
    <% f.buttons do %>
      <%= submit_tag "Confirm" %>
      <%= submit_tag "Cancel", :name => "cancel", :class=>"submit-other" %>
    <% end  %>
  <% end %>

View:

  <% render :layout => '/layouts/confirm',
            :locals => { :entity => @voucher } do |ignore, f| %>
      <%= f.input :redeemed_by, :label=>"Voucher Used By"  %>
  <% end %>

TADA!