From a7b328552eb0d36315f75bff813bea7eecf8c1d7 Mon Sep 17 00:00:00 2001 From: Pavel Pravosud Date: Wed, 8 Oct 2014 00:17:54 -0400 Subject: [PATCH] Fix `Jbuilder#merge!` inside block --- lib/jbuilder.rb | 32 +++++++++++++------------------- test/jbuilder_test.rb | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+), 19 deletions(-) diff --git a/lib/jbuilder.rb b/lib/jbuilder.rb index 9ca49df..c90a6a6 100644 --- a/lib/jbuilder.rb +++ b/lib/jbuilder.rb @@ -255,18 +255,25 @@ def _extract_method_values(object, *attributes) def _merge_block(key, &block) current_value = _blank? ? BLANK : @attributes.fetch(_key(key), BLANK) raise NullError.build(key) if current_value.nil? + new_value = _scope{ yield self } + _merge_values(current_value, new_value) + end - value = _scope{ yield self } - - if _blank?(value) + def _merge_values(current_value, updates) + if _blank?(updates) current_value - elsif _blank?(current_value) || value.nil? - value + elsif _blank?(current_value) || updates.nil? + updates + elsif ::Array === updates + current_value = ::Array === current_value ? current_value.dup : [] + current_value.concat updates else - _merge_values(current_value, value) + current_value = current_value.dup + current_value.update updates end end + def _write(key, value) @attributes = {} if _blank? @attributes[_key(key)] = value @@ -302,19 +309,6 @@ def _mapable_arguments?(value, *args) value.respond_to?(:map) end - def _merge_values(attributes, hash_or_array) - attributes = attributes.dup - - if ::Array === hash_or_array - attributes = [] unless ::Array === attributes - attributes.concat hash_or_array - else - attributes.update hash_or_array - end - - attributes - end - def _blank?(value=@attributes) BLANK == value end diff --git a/test/jbuilder_test.rb b/test/jbuilder_test.rb index 0e38a81..74a5459 100644 --- a/test/jbuilder_test.rb +++ b/test/jbuilder_test.rb @@ -157,6 +157,24 @@ class JbuilderTest < ActiveSupport::TestCase assert_equal 32, result['author']['age'] end + test 'support merge! method' do + result = jbuild do |json| + json.merge! 'foo' => 'bar' + end + + assert_equal 'bar', result['foo'] + end + + test 'support merge! method in a block' do + result = jbuild do |json| + json.author do + json.merge! 'name' => 'Pavel' + end + end + + assert_equal 'Pavel', result['author']['name'] + end + test 'blocks are additive via extract syntax' do person = Person.new('Pavel', 27)