diff options
author | Aaron Patterson <aaron.patterson@gmail.com> | 2013-09-25 11:25:36 -0700 |
---|---|---|
committer | Aaron Patterson <aaron.patterson@gmail.com> | 2013-09-25 11:25:36 -0700 |
commit | e2fd64fe469037644711a65a00270bea15ee2955 (patch) | |
tree | a7374d295e2f8e137593171ae99d2d6102d868bc /actionview | |
parent | 70e48a6ac34615ba5ed3b807917c3b099256d67c (diff) | |
parent | f3982858359008ec8fe43b8fa2c75aad8788cd89 (diff) | |
download | rails-e2fd64fe469037644711a65a00270bea15ee2955.tar.gz rails-e2fd64fe469037644711a65a00270bea15ee2955.tar.bz2 rails-e2fd64fe469037644711a65a00270bea15ee2955.zip |
Merge branch 'master' into preload
* master: (62 commits)
Getting Started Guide: Hello Rails! -> Hello, Rails! and wrap code tag
Add CHANGELOG entry for #12344
Add regression test to #12343
Fix typo in number_to_human docs: you -> your
[Documentation] Add a missing validation to I18n docs
Use the given name in html_options for the hidden field in collection_check_boxes
assign_attributes should return if argument is blank.
No need the else clause
Use join to concat the both side of the AST
Add a CHANGELOG entry about Web Console inclusion
added column type to example in section 2.3
Include web-console in new projects Gemfile
ActiveRecord::ConnectionAdapters::Column.string_to_time method respects string with timezone. Closes #12278.
add test_scoped_root_as_name
Getting Started Guide: update RubyGems Guides link [ci skip]
Deprecate unused quoted_locking_column method.
Update references to wycats/thor to erikhuda/thor.
bcrypt-ruby v3.1.2 supports Ruby 2.0 on Windows
Fix the model name in the association basics guides
We shouldn't override PostgreSQLAdapter's superclass inheritance while monkeypatching
...
Diffstat (limited to 'actionview')
17 files changed, 161 insertions, 28 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md index 53142a835e..a09650c559 100644 --- a/actionview/CHANGELOG.md +++ b/actionview/CHANGELOG.md @@ -1,3 +1,26 @@ +* Fix `collection_check_boxes` generated hidden input to use the name attribute provided + in the options hash. + + *Angel N. Sciortino* + +* Fix some edge cases for AV `select` helper with `:selected` option + + *Bogdan Gusiev* + +* Ability to pass block to `select` helper + + <%= select(report, "campaign_ids") do %> + <% available_campaigns.each do |c| -%> + <%= content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json }) %> + <% end -%> + <% end -%> + + *Bogdan Gusiev* + +* Handle `:namespace` form option in collection labels + + *Vasiliy Ermolovich* + * Fix `form_for` when both `namespace` and `as` options are present `as` option no longer overwrites `namespace` option when generating @@ -13,6 +36,12 @@ *Josh Lauer*, *Justin Ridgewell* +* Fixed a bug where the lookup details were not being taken into account + when caching the digest of a template - changes to the details now + cause a different cache key to be used. + + *Daniel Schierbeck* + * Added an `extname` hash option for `javascript_include_tag` method. Before: diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb index 95c3200c81..af158a630b 100644 --- a/actionview/lib/action_view/digestor.rb +++ b/actionview/lib/action_view/digestor.rb @@ -10,7 +10,10 @@ module ActionView class << self def digest(name, format, finder, options = {}) - cache_key = ([name, format] + Array.wrap(options[:dependencies])).join('.') + details_key = finder.details_key.hash + dependencies = Array.wrap(options[:dependencies]) + cache_key = ([name, details_key, format] + dependencies).join('.') + # this is a correctly done double-checked locking idiom # (ThreadSafe::Cache's lookups have volatile semantics) @@cache[cache_key] || @@digest_monitor.synchronize do diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb index fcd151ac32..4347983bad 100644 --- a/actionview/lib/action_view/helpers/form_options_helper.rb +++ b/actionview/lib/action_view/helpers/form_options_helper.rb @@ -128,6 +128,15 @@ module ActionView # or <tt>selected: nil</tt> to leave all options unselected. Similarly, you can specify values to be disabled in the option # tags by specifying the <tt>:disabled</tt> option. This can either be a single value or an array of values to be disabled. # + # A block can be passed to +select+ to customize how the options tags will be rendered. This + # is useful when the options tag has complex attributes. + # + # select(report, "campaign_ids") do + # available_campaigns.each do |c| + # content_tag(:option, c.name, value: c.id, data: { tags: c.tags.to_json }) + # end + # end + # # ==== Gotcha # # The HTML specification says when +multiple+ parameter passed to select and all options got deselected @@ -152,8 +161,8 @@ module ActionView # In case if you don't want the helper to generate this hidden field you can specify # <tt>include_hidden: false</tt> option. # - def select(object, method, choices, options = {}, html_options = {}) - Tags::Select.new(object, method, self, choices, options, html_options).render + def select(object, method, choices = nil, options = {}, html_options = {}, &block) + Tags::Select.new(object, method, self, choices, options, html_options, &block).render end # Returns <tt><select></tt> and <tt><option></tt> tags for the collection of existing return values of @@ -766,8 +775,8 @@ module ActionView # <% end %> # # Please refer to the documentation of the base helper for details. - def select(method, choices, options = {}, html_options = {}) - @template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options)) + def select(method, choices = nil, options = {}, html_options = {}, &block) + @template.select(@object_name, method, choices, objectify_options(options), @default_options.merge(html_options), &block) end # Wraps ActionView::Helpers::FormOptionsHelper#collection_select for form builders: diff --git a/actionview/lib/action_view/helpers/tags/base.rb b/actionview/lib/action_view/helpers/tags/base.rb index 3fe3f4e9df..8607da301c 100644 --- a/actionview/lib/action_view/helpers/tags/base.rb +++ b/actionview/lib/action_view/helpers/tags/base.rb @@ -119,7 +119,8 @@ module ActionView html_options = html_options.stringify_keys add_default_name_and_id(html_options) options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options) - select = content_tag("select", add_options(option_tags, options, value(object)), html_options) + value = options.fetch(:selected) { value(object) } + select = content_tag("select", add_options(option_tags, options, value), html_options) if html_options["multiple"] && options.fetch(:include_hidden, true) tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select diff --git a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb index 52006d856b..9b77ebeb1b 100644 --- a/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb +++ b/actionview/lib/action_view/helpers/tags/collection_check_boxes.rb @@ -27,7 +27,8 @@ module ActionView # Append a hidden field to make sure something will be sent back to the # server if all check boxes are unchecked. - hidden = @template_object.hidden_field_tag("#{tag_name}[]", "", :id => nil) + hidden_name = @html_options[:name] || "#{tag_name}[]" + hidden = @template_object.hidden_field_tag(hidden_name, "", :id => nil) rendered_collection + hidden end diff --git a/actionview/lib/action_view/helpers/tags/collection_helpers.rb b/actionview/lib/action_view/helpers/tags/collection_helpers.rb index 388dcf1f13..787039c82e 100644 --- a/actionview/lib/action_view/helpers/tags/collection_helpers.rb +++ b/actionview/lib/action_view/helpers/tags/collection_helpers.rb @@ -18,7 +18,8 @@ module ActionView end def label(label_html_options={}, &block) - @template_object.label(@object_name, @sanitized_attribute_name, @text, label_html_options, &block) + html_options = label_html_options.merge(@input_html_options) + @template_object.label(@object_name, @sanitized_attribute_name, @text, html_options, &block) end end diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb index 35d3ba8434..180aa9ac27 100644 --- a/actionview/lib/action_view/helpers/tags/label.rb +++ b/actionview/lib/action_view/helpers/tags/label.rb @@ -30,6 +30,7 @@ module ActionView add_default_name_and_id_for_value(tag_value, name_and_id) options.delete("index") options.delete("namespace") + options.delete("multiple") options["for"] = name_and_id["id"] unless options.key?("for") if block_given? diff --git a/actionview/lib/action_view/helpers/tags/select.rb b/actionview/lib/action_view/helpers/tags/select.rb index d64e2f68ef..00881d9978 100644 --- a/actionview/lib/action_view/helpers/tags/select.rb +++ b/actionview/lib/action_view/helpers/tags/select.rb @@ -3,8 +3,9 @@ module ActionView module Tags # :nodoc: class Select < Base # :nodoc: def initialize(object_name, method_name, template_object, choices, options, html_options) - @choices = choices + @choices = block_given? ? template_object.capture { yield } : choices @choices = @choices.to_a if @choices.is_a?(Range) + @html_options = html_options super(object_name, method_name, template_object, options) diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb index 1920a94567..8a4918a8c0 100644 --- a/actionview/lib/action_view/helpers/url_helper.rb +++ b/actionview/lib/action_view/helpers/url_helper.rb @@ -92,8 +92,9 @@ module ActionView # ==== Data attributes # # * <tt>confirm: 'question?'</tt> - This will allow the unobtrusive JavaScript - # driver to prompt with the question specified. If the user accepts, the link is - # processed normally, otherwise no action is taken. + # driver to prompt with the question specified (in this case, the + # resulting text would be <tt>question?</tt>. If the user accepts, the + # link is processed normally, otherwise no action is taken. # * <tt>:disable_with</tt> - Value of this parameter will be # used as the value for a disabled version of the submit # button when the form is submitted. This feature is provided diff --git a/actionview/test/fixtures/helpers/fun/games_helper.rb b/actionview/test/fixtures/helpers/fun/games_helper.rb deleted file mode 100644 index 3b7adce086..0000000000 --- a/actionview/test/fixtures/helpers/fun/games_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Fun - module GamesHelper - def stratego() "Iz guuut!" end - end -end
\ No newline at end of file diff --git a/actionview/test/fixtures/helpers/fun/pdf_helper.rb b/actionview/test/fixtures/helpers/fun/pdf_helper.rb deleted file mode 100644 index 0171be8500..0000000000 --- a/actionview/test/fixtures/helpers/fun/pdf_helper.rb +++ /dev/null @@ -1,5 +0,0 @@ -module Fun - module PdfHelper - def foobar() 'baz' end - end -end diff --git a/actionview/test/fixtures/helpers/just_me_helper.rb b/actionview/test/fixtures/helpers/just_me_helper.rb deleted file mode 100644 index b140a7b9b4..0000000000 --- a/actionview/test/fixtures/helpers/just_me_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -module JustMeHelper - def me() "mine!" end -end
\ No newline at end of file diff --git a/actionview/test/fixtures/helpers/me_too_helper.rb b/actionview/test/fixtures/helpers/me_too_helper.rb deleted file mode 100644 index ce56042143..0000000000 --- a/actionview/test/fixtures/helpers/me_too_helper.rb +++ /dev/null @@ -1,3 +0,0 @@ -module MeTooHelper - def me() "me too!" end -end
\ No newline at end of file diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb index c6608e214a..0f6b14a57d 100644 --- a/actionview/test/template/digestor_test.rb +++ b/actionview/test/template/digestor_test.rb @@ -15,6 +15,16 @@ end class FixtureFinder FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor" + attr_reader :details + + def initialize + @details = {} + end + + def details_key + details.hash + end + def find(logical_name, keys, partial, options) FixtureTemplate.new("digestor/#{partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name}.#{options[:formats].first}.erb") end @@ -140,6 +150,20 @@ class TemplateDigestorTest < ActionView::TestCase end end + def test_details_are_included_in_cache_key + # Cache the template digest. + old_digest = digest("events/_event") + + # Change the template; the cached digest remains unchanged. + change_template("events/_event") + + # The details are changed, so a new cache key is generated. + finder.details[:foo] = "bar" + + # The cache is busted. + assert_not_equal old_digest, digest("events/_event") + end + def test_extra_whitespace_in_render_partial assert_digest_difference("messages/edit") do change_template("messages/_form") @@ -220,7 +244,11 @@ class TemplateDigestorTest < ActionView::TestCase end def digest(template_name, options={}) - ActionView::Digestor.digest(template_name, :html, FixtureFinder.new, options) + ActionView::Digestor.digest(template_name, :html, finder, options) + end + + def finder + @finder ||= FixtureFinder.new end def change_template(template_name) diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb index b56847396d..d28e4aeb48 100644 --- a/actionview/test/template/form_collections_helper_test.rb +++ b/actionview/test/template/form_collections_helper_test.rb @@ -179,6 +179,13 @@ class FormCollectionsHelperTest < ActionView::TestCase assert_select "input[type=hidden][name='user[category_ids][]'][value=]", :count => 1 end + test 'collection check boxes generates a hidden field using the given :name in :html_options' do + collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')] + with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, {name: "user[other_category_ids][]"} + + assert_select "input[type=hidden][name='user[other_category_ids][]'][value=]", :count => 1 + end + test 'collection check boxes accepts a collection and generate a serie of checkboxes with labels for label method' do collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')] with_collection_check_boxes :user, :category_ids, collection, :id, :name diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb index 944884c9dd..3e8a2468ed 100644 --- a/actionview/test/template/form_helper_test.rb +++ b/actionview/test/template/form_helper_test.rb @@ -1282,6 +1282,24 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_with_namespace_and_with_collection_radio_buttons + post = Post.new + def post.active; false; end + + form_for(post, namespace: 'foo') do |f| + concat f.collection_radio_buttons(:active, [true, false], :to_s, :to_s) + end + + expected = whole_form("/posts", "foo_new_post", "new_post") do + "<input id='foo_post_active_true' name='post[active]' type='radio' value='true' />" + + "<label for='foo_post_active_true'>true</label>" + + "<input checked='checked' id='foo_post_active_false' name='post[active]' type='radio' value='false' />" + + "<label for='foo_post_active_false'>false</label>" + end + + assert_dom_equal expected, output_buffer + end + def test_form_for_with_collection_check_boxes post = Post.new def post.tag_ids; [1, 3]; end @@ -1361,6 +1379,24 @@ class FormHelperTest < ActionView::TestCase assert_dom_equal expected, output_buffer end + def test_form_with_namespace_and_with_collection_check_boxes + post = Post.new + def post.tag_ids; [1]; end + collection = [[1, "Tag 1"]] + + form_for(post, namespace: 'foo') do |f| + concat f.collection_check_boxes(:tag_ids, collection, :first, :last) + end + + expected = whole_form("/posts", "foo_new_post", "new_post") do + "<input checked='checked' id='foo_post_tag_ids_1' name='post[tag_ids][]' type='checkbox' value='1' />" + + "<label for='foo_post_tag_ids_1'>Tag 1</label>" + + "<input name='post[tag_ids][]' type='hidden' value='' />" + end + + assert_dom_equal expected, output_buffer + end + def test_form_for_with_file_field_generate_multipart Post.send :attr_accessor, :file diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb index a6977766d1..50e9d132a7 100644 --- a/actionview/test/template/form_options_helper_test.rb +++ b/actionview/test/template/form_options_helper_test.rb @@ -556,6 +556,21 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_select_under_fields_for_with_block + @post = Post.new + + output_buffer = fields_for :post, @post do |f| + concat(f.select(:category) do + concat content_tag(:option, "hello world") + end) + end + + assert_dom_equal( + "<select id=\"post_category\" name=\"post[category]\"><option>hello world</option></select>", + output_buffer + ) + end + def test_select_with_multiple_to_add_hidden_input output_buffer = select(:post, :category, "", {}, :multiple => true) assert_dom_equal( @@ -783,6 +798,22 @@ class FormOptionsHelperTest < ActionView::TestCase ) end + def test_select_not_existing_method_with_selected_value + @post = Post.new + assert_dom_equal( + "<select id=\"post_locale\" name=\"post[locale]\"><option value=\"en\">en</option>\n<option value=\"ru\" selected=\"selected\">ru</option></select>", + select("post", "locale", %w( en ru ), :selected => 'ru') + ) + end + + def test_select_with_prompt_and_selected_value + @post = Post.new + assert_dom_equal( + "<select id=\"post_category\" name=\"post[category]\"><option value=\"one\">one</option>\n<option selected=\"selected\" value=\"two\">two</option></select>", + select("post", "category", %w( one two ), :selected => 'two', :prompt => true) + ) + end + def test_select_with_disabled_array @post = Post.new @post.category = "<mus>" |