middleman / middleman

Hand-crafted frontend development
https://middlemanapp.com
MIT License
7.04k stars 746 forks source link

Form Helper: select_tag throws Error #1092

Closed cvkef closed 10 years ago

cvkef commented 10 years ago
Full stack trace
TypeError: can't convert nil into String
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/activesupport-3.2.15/lib/active_support/core_ext/string/output_safety.rb:114:in `concat'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/activesupport-3.2.15/lib/active_support/core_ext/string/output_safety.rb:114:in `safe_concat'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:52:in `block in content_tag'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:52:in `each'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:52:in `content_tag'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/vendored-middleman-deps/padrino-helpers-0.11.2/lib/padrino-helpers/tag_helpers.rb:140:in `safe_content_tag'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/vendored-middleman-deps/padrino-helpers-0.11.2/lib/padrino-helpers/form_helpers.rb:646:in `select_tag'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:13:in `block (3 levels) in singletonclass'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:10:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:10:in `capture_from_template'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:65:in `capture_html'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/vendored-middleman-deps/padrino-helpers-0.11.2/lib/padrino-helpers/form_helpers.rb:133:in `field_set_tag'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:9:in `block (2 levels) in singletonclass'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:10:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:10:in `capture_from_template'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:65:in `capture_html'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/vendored-middleman-deps/padrino-helpers-0.11.2/lib/padrino-helpers/form_helpers.rb:87:in `form_tag'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-more/core_extensions/default_helpers.rb:232:in `form_tag'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:8:in `block in singletonclass'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:65530:in `instance_eval'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:65530:in `singletonclass'
    /Volumes/CvK_1T/Projects/MiddleMan/test/source/index.html.erb:65528:in `__tilt_70131410598780'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/tilt-1.3.7/lib/tilt/template.rb:144:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/tilt-1.3.7/lib/tilt/template.rb:144:in `evaluate'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/tilt-1.3.7/lib/tilt/template.rb:77:in `render'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/rendering.rb:280:in `render_individual_file'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/rendering.rb:157:in `render_template'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/sitemap/resource.rb:149:in `block in render'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/activesupport-3.2.15/lib/active_support/notifications.rb:125:in `instrument'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/util.rb:63:in `instrument'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/application.rb:196:in `instrument'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/sitemap/resource.rb:16:in `instrument'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/sitemap/resource.rb:120:in `render'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/request.rb:254:in `process_request'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/request.rb:204:in `block in call!'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/request.rb:203:in `catch'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/request.rb:203:in `call!'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/middleman-core-3.2.0/lib/middleman-core/core_extensions/request.rb:189:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:138:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/urlmap.rb:65:in `block in call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/urlmap.rb:50:in `each'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/urlmap.rb:50:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/showexceptions.rb:24:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/head.rb:11:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/lint.rb:49:in `_call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/lint.rb:37:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/builder.rb:138:in `call'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/gems/1.9.1/gems/rack-1.5.2/lib/rack/handler/webrick.rb:60:in `service'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/webrick/httpserver.rb:138:in `service'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/webrick/httpserver.rb:94:in `run'
    /Users/CvK/.rbenv/versions/1.9.3-p448/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread'
How to reproduce

Create a new middleman project and just render a form with a select_tag on index.html.erb.

<%= select_tag  :strategy, options: ['delete', 'destroy'] %>
Dirty Workaround

Override select_tag at config.rb and join the _select_optionshtml

helpers do
  def select_tag(name, options={})
    .
    .
    .
    safe_content_tag(:select, select_options_html.join, options)
  end
end
Weird Workaround

Just override content_tag at config.rb with the original _contenttag method

helpers do
  def content_tag(name, content = nil, options = nil, &block)
    if block_given?
      options = content if content.is_a?(Hash)
      content = capture_html(&block)
    end

    options    = parse_data_options(name, options)
    attributes = tag_attributes(options)
    output = ActiveSupport::SafeBuffer.new
    output.safe_concat "<#{name}#{attributes}>"
    if content.respond_to?(:each) && !content.is_a?(String)
      content.each { |c| output.concat c; output.safe_concat NEWLINE }
    else
      output.concat content
    end
    output.safe_concat "</#{name}>"

    block_is_template?(block) ? concat_content(output) : output
  end
end
tdreyno commented 10 years ago

Weird indeed, I'll add some tests. Anything the SafeBuffer touches is a PITA.

coffeencoke commented 10 years ago

I was running into this problem earlier today, it happened when I didn't provide a include_blank option to the select_tag method.

I think the problem is happening before it even gets to the content_tag method, for some reason, the content contains nil for the first element in the array when select_tag is given an array, and is not given a value for the include_blank option.

I created a cuke to test this: https://github.com/coffeencoke/middleman/commit/4e7297904f84683b38e8e964946730b0c6a29159

You can run it and inspect the content which ends up looking like this:

>> content
=> [nil, "<option value=\"red\">red</option>red</option>", "<option value=\"blue\">blue</option>", "<option value=\"blorange\">blorange</option>"]
coffeencoke commented 10 years ago

I added the pull request above which does fix the issue, but I think it would be best to submit this directly to Padrino, and have it fixed at the source.

coffeencoke commented 10 years ago

It looks like padrino's master version is much different than the 0.11.4 version so it may already be fixed in padrino's master.

bhollis commented 10 years ago

Closing since we're on Padrino 0.12 now.