<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kickass Labs &#187; invalidauthenticitytoken</title>
	<atom:link href="http://www.kickasslabs.com/tag/invalidauthenticitytoken/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kickasslabs.com</link>
	<description>We &#9829; code.</description>
	<lastBuildDate>Wed, 28 Dec 2011 16:57:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>InvalidAuthenticityToken, Forms, Tables, and Rails</title>
		<link>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/</link>
		<comments>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 19:12:41 +0000</pubDate>
		<dc:creator>gabe</dc:creator>
				<category><![CDATA[HTML]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[forms]]></category>
		<category><![CDATA[invalidauthenticitytoken]]></category>
		<category><![CDATA[tables]]></category>

		<guid isPermaLink="false">http://www.kickasslabs.com/?p=167</guid>
		<description><![CDATA[Recently, while pairing with Abel as we hacked on some code for his budget tracking app, we came across an interesting problem while trying to acomplish what seems like a pretty straightforward task. The Context: We had a table of &#8230; <a href="http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Recently, while pairing with Abel as we hacked on some code for his budget tracking app, we came across an interesting problem while trying to acomplish what seems like a pretty straightforward task.</p>
<p><span id="more-167"></span></p>
<p><strong>The Context</strong>: We had a table of records were using remote_form_for to output an edit form for each row so that we could allow inline editing of any row via AJAX.  The code looked something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="haml" style="font-family:monospace;">-remote_form_for(person) do |f|
  %tr
    %td
      =f.text_field :first_name
    %td
      =f.text_field :last_name
    %td
      =f.submit 'Save'</pre></div></div>

<p>If you prefer straight HTML, the relevant code looked something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;form&gt;
&lt;input name=&quot;person[first_name]&quot; type=&quot;text&quot; /&gt;
&lt;input name=&quot;person[last_name]&quot; type=&quot;text&quot; /&gt;
&lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;
&lt;/form&gt;</pre></div></div>

<p><strong>The Problem</strong>: When submitting an edit on any of the people rows, we would see an ActionController::InvalidAuthenticityToken exception in the server log.  This error is usually a sign of a configuration problem with your environment, but our case seemed different.  Firebug showed us that the browser didn&#8217;t appear to be passing any params to the server during it&#8217;s update post and the server log didn&#8217;t show any params coming through, either.  So, it wasn&#8217;t an invalid authenticity token being passed; no token was being pased at all.  I would prefer if Rails gave us a MissingAuthenticityToken error instead but I digress.</p>
<p><strong>The Discovery</strong>: After whipping up a test case where we had a remote form on a page working fine with no errors, we discovered that the problem only occured when the form was wrapping the record&#8217;s table row tag in the view.  And, well, this makes a good deal of sense.  Here&#8217;s what the <a href="http://www.w3.org/TR/html401/sgml/dtd.html#block">HTML 4.01 spec</a> says about FORMs and TABLEs (relevant lines from the spec have been pasted below in a convenient order):</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;!--ELEMENT TABLE - -
     (CAPTION?, (COL*|COLGROUP*), THEAD?, TFOOT?, TBODY+)--&gt;
&lt;!--ELEMENT TBODY O O (TR)+   table body  --&gt;
&lt;!--ELEMENT TR       - O (TH|TD)+          table row  --&gt;
&lt;!--ELEMENT (TH|TD)  - O (%flow;)*         table header cell, table data cell --&gt;
&lt;!--ENTITY % flow &quot;%block; | %inline;&quot;--&gt;
&lt;!--ENTITY % block
     &quot;P | %heading; | %list; | %preformatted; | DL | DIV | NOSCRIPT |
      BLOCKQUOTE | FORM | HR | TABLE | FIELDSET | ADDRESS&quot;--&gt;</pre></div></div>

<p>If you&#8217;re not used to looking at DTDs, all that synax can be hard to grok.  Here&#8217;s what the relevant parts of it say, in plain English:</p>
<ul>
<li>TABLEs must have a TBODY</li>
<li>TBODYs must have a TR</li>
<li>TRs must have THs or TDs</li>
<li>TDs can have any elements inside them as long as those elements belong to the <em>flow</em> group</li>
<li>The <em>flow</em> group consists of elements inside the <em>block</em> group and the <em>inline</em> group</li>
<li>FORM elements are part of the <em>block</em> group.</li>
</ul>
<p>So, what was happening was that the browser saw our FORM element defined as a sibling to the TR.  That&#8217;s not allowed in the spec, so it makes some bit of sense that the browser wouldn&#8217;t pass the form data to the server the way we expect it would.  After all, the browser is dealing with invalid markup here.</p>
<p><strong>The Solution</strong>: The solution we found was to wrap the form input controls inside one big table that&#8217;s wrapped by the form tag, like this:</p>

<div class="wp_syntax"><div class="code"><pre class="haml" style="font-family:monospace;">%table
  -@people.each do |person|
    %tr
      %td
        -remote_form_for(person) do |f|
          %table
            %tr
              %td
                =f.text_field :first_name
              %td
                =f.text_field :last_name
              %td
                =f.submit 'Save'</pre></div></div>

<p>Again, in HTML:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;table border=&quot;0&quot;&gt;
  &amp;lt;% @people.each do |person| %&amp;gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;form&gt;
&lt;table border=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;input name=&quot;person[first_name]&quot; type=&quot;text&quot; /&gt;&lt;/td&gt;
&lt;td&gt;
&lt;input name=&quot;person[last_name]&quot; type=&quot;text&quot; /&gt;&lt;/td&gt;
&lt;td&gt;
&lt;input type=&quot;submit&quot; value=&quot;Save&quot; /&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/form&gt;&lt;/td&gt;
&lt;/tr&gt;
&amp;lt;% end %&amp;gt;&lt;/tbody&gt;&lt;/table&gt;</pre></div></div>

<p>Note: at this point we&#8217;re using a table for layout, and it&#8217;s nasty as all hell.  <strong>I don&#8217;t recommend that you structure your markup this way.</strong></p>
<p>But, <strong>this example illustrates is how you can use a FORM element inside of a TABLE and have it actually work</strong>.  And, more importantly, now we know why we were getting an InvalidAuthenticityToken error when everything seemed like it should have worked.</p>
<p>Hope this helps anyone else in the same situation.</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.kickasslabs.com%2F2009%2F03%2F01%2Finvalidauthenticitytoken-forms-tables-and-rails%2F&amp;title=InvalidAuthenticityToken%2C%20Forms%2C%20Tables%2C%20and%20Rails" id="wpa2a_2"><img src="http://www.kickasslabs.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.kickasslabs.com/2009/03/01/invalidauthenticitytoken-forms-tables-and-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

