Entries from October 2008 ↓

Fixing CSRF and Rails’ Form Tag Helper

I’d love a sanity check on this, but as far as I can tell it’s impossible to have an inline form in Rails if you are using cross site request forgery protection.

Rails’ form tag helper helpfully puts a hidden field in with an authenticity token. Unfortunately, it wraps the hidden field in a div! So even if your form has style=”display:inline”, the div won’t.. and you won’t be able to display a form that doesn’t force a newline.

Here’s a solution: create config/initializers/fix_form_tag_helper.rb to override the form_tag_helper:

module ActionView::Helpers::FormTagHelper
  def extra_tags_for_form(html_options)
    case method = html_options.delete("method").to_s
    when /^get$/i # must be case-insentive, but can't use downcase as might be nil
      html_options["method"] = “get”
      ”
    when /^post$/i, “”, nil
      html_options["method"] = “post”
      #Rails puts a div around the hidden tag, that’s ridiculous
      #protect_against_forgery? ? content_tag(:div, token_tag, :style => ‘margin:0;padding:0′) : ”
      protect_against_forgery? ? token_tag : ”
    else
      html_options["method"] = “post”
      #Rails puts a div around the hidden tag, that’s ridiculous
      #content_tag(:div, tag(:input, :type => “hidden”, :name => “_method”, :value => method) + token_tag, :style => ‘margin:0;padding:0′)
      tag(:input, :type => “hidden”, :name => “_method”, :value => method) + token_tag
    end
  end
end

That does the trick!