diff --git a/CHANGELOG.md b/CHANGELOG.md index 374a2102..5fb8ce7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ * Dropped support for Rails `< 4.2` * Dropped support for Ruby `< 2.4` +### New features + +* Add `merge_hash_arrays` as a configuration option ([#214](https://github.com/railsconfig/config/pull/214)) + ### Changes * Upgraded dry-validation dependency to dry-schema 1.0 ([#224](https://github.com/railsconfig/config/pull/224)) diff --git a/README.md b/README.md index b3c7212a..dfdc88ef 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,7 @@ located at `config/initializers/config.rb`. ### Merge customization * `overwrite_arrays` - overwrite arrays found in previously loaded settings file. Default: `true` +* `merge_hash_arrays` - merge hashes inside of arrays from previously loaded settings files. Makes sense only when `overwrite_arrays = false`. Default: `false` * `knockout_prefix` - ability to remove elements of the array set in earlier loaded settings file. Makes sense only when `overwrite_arrays = false`, otherwise array settings would be overwritten by default. Default: `nil` * `merge_nil_values` - `nil` values will overwrite an existing value when merging configs. Default: `true`. diff --git a/lib/config.rb b/lib/config.rb index 11c43d91..dfbba30e 100644 --- a/lib/config.rb +++ b/lib/config.rb @@ -26,10 +26,11 @@ module Config @@fail_on_missing = false # deep_merge options - mattr_accessor :knockout_prefix, :merge_nil_values, :overwrite_arrays + mattr_accessor :knockout_prefix, :merge_nil_values, :overwrite_arrays, :merge_hash_arrays @@knockout_prefix = nil @@merge_nil_values = true @@overwrite_arrays = true + @@merge_hash_arrays = false def self.setup yield self if @@_ran_once == false diff --git a/lib/config/options.rb b/lib/config/options.rb index f4f7f9f9..5e4156ce 100644 --- a/lib/config/options.rb +++ b/lib/config/options.rb @@ -82,7 +82,8 @@ def reload! preserve_unmergeables: false, knockout_prefix: Config.knockout_prefix, overwrite_arrays: Config.overwrite_arrays, - merge_nil_values: Config.merge_nil_values + merge_nil_values: Config.merge_nil_values, + merge_hash_arrays: Config.merge_hash_arrays ) end end @@ -134,7 +135,8 @@ def merge!(hash) preserve_unmergeables: false, knockout_prefix: Config.knockout_prefix, overwrite_arrays: Config.overwrite_arrays, - merge_nil_values: Config.merge_nil_values + merge_nil_values: Config.merge_nil_values, + merge_hash_arrays: Config.merge_hash_arrays ) marshal_load(__convert(current).marshal_dump) self diff --git a/spec/fixtures/deep_merge3/config1.yml b/spec/fixtures/deep_merge3/config1.yml new file mode 100644 index 00000000..c277eeab --- /dev/null +++ b/spec/fixtures/deep_merge3/config1.yml @@ -0,0 +1 @@ +array: [{a: "one"}] diff --git a/spec/fixtures/deep_merge3/config2.yml b/spec/fixtures/deep_merge3/config2.yml new file mode 100644 index 00000000..413dac30 --- /dev/null +++ b/spec/fixtures/deep_merge3/config2.yml @@ -0,0 +1 @@ +array: [{b: "two"}] diff --git a/spec/options_spec.rb b/spec/options_spec.rb index 504f0150..bc0e7025 100644 --- a/spec/options_spec.rb +++ b/spec/options_spec.rb @@ -179,4 +179,40 @@ expect(config.key?('existing')).to eq(false) end end + + context 'when merge_hash_arrays options' do + before { Config.reset } + + context 'is set to true' do + before { Config.setup { |cfg| + cfg.overwrite_arrays = false + cfg.merge_hash_arrays = true + } } + + it 'should merge the arrays' do + config = Config.load_files("#{fixture_path}/deep_merge3/config1.yml", "#{fixture_path}/deep_merge3/config2.yml") + + expect(config.array.length).to eq(1) + expect(config.array[0].a).to eq("one") + expect(config.array[0].b).to eq("two") + end + end + + context 'is set to false' do + before { Config.setup { |cfg| + cfg.overwrite_arrays = false + cfg.merge_hash_arrays = false + } } + + it 'should merge the arrays' do + config = Config.load_files("#{fixture_path}/deep_merge3/config1.yml", "#{fixture_path}/deep_merge3/config2.yml") + + expect(config.array.length).to eq(2) + expect(config.array[0].b).to eq(nil) + expect(config.array[1].b).to eq("two") + end + end + + end + end