Skip to content

Commit

Permalink
Change the default behavior for arrays from merging to overwriting (f…
Browse files Browse the repository at this point in the history
…ixes rubyconfig#12)
  • Loading branch information
hnakamur committed Dec 24, 2014
1 parent 8375d71 commit d5dc9f2
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 4 deletions.
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,46 @@ It won't work with arrays, though.

To upload your local values to Heroku you could ran `bundle exec rake rails_config:heroku`.

## Overwriting or Merging Arrays

We changed the default behavior for arrays from merging to overwriting. Eg:

settings.yml

```yaml
some_array:
- 1
- 2
```
settings.local.yml
```yaml
some_array:
- 3
- 4
```
config/initializers/rails_config.rb
```ruby
RailsConfig.setup do |config|
config.const_name = 'settings'
end
```

`Settings.some_array` becomes `[3, 4]`.

If you want the old behavior (merging arrays), just set the `overwrite_arrays` var to `false` in your `config/initializers/rails_config.rb` file. Eg:

```ruby
RailsConfig.setup do |config|
config.overwrite_arrays = false
config.const_name = 'settings'
end
```

`Settings.some_array` becomes `[1, 2, 3, 4]`.

## Contributing

Expand Down
4 changes: 3 additions & 1 deletion lib/rails_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ module RailsConfig
# ensures the setup only gets run once
@@_ran_once = false

mattr_accessor :const_name, :use_env
mattr_accessor :const_name, :use_env, :overwrite_arrays
@@const_name = "Settings"
@@use_env = false
@@overwrite_arrays = true

def self.setup
yield self if @@_ran_once == false
Expand All @@ -23,6 +24,7 @@ def self.setup
# if the first file if they exist in the first file.
def self.load_files(*files)
config = Options.new
config.overwrite_arrays = overwrite_arrays

# add yaml sources
[files].flatten.compact.uniq.each do |file|
Expand Down
5 changes: 3 additions & 2 deletions lib/rails_config/options.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module RailsConfig
class Options < OpenStruct
include Enumerable
attr_accessor :overwrite_arrays

def keys() marshal_dump.keys; end
def empty?() marshal_dump.empty?; end
Expand All @@ -23,7 +24,7 @@ def reload_env!
key.to_s.split('.').reverse.each do |element|
hash = {element => hash}
end
DeepMerge.deep_merge!(hash, conf, :preserve_unmergeables => false)
DeepMerge.deep_merge!(hash, conf, :preserve_unmergeables => false, :overwrite_arrays => overwrite_arrays)
end

merge!(conf[RailsConfig.const_name] || {})
Expand All @@ -40,7 +41,7 @@ def reload!
if conf.empty?
conf = source_conf
else
DeepMerge.deep_merge!(source_conf, conf, :preserve_unmergeables => false)
DeepMerge.deep_merge!(source_conf, conf, :preserve_unmergeables => false, :overwrite_arrays => overwrite_arrays)
end
end

Expand Down
7 changes: 6 additions & 1 deletion lib/rails_config/vendor/deep_merge.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class InvalidParameter < StandardError; end
# Set to true to skip any unmergeable elements from source
# :knockout_prefix DEFAULT: nil
# Set to string value to signify prefix which deletes elements from existing element
# :overwrite_arrays DEFAULT: true
# Set to true to overwrite arrays intead of merging elements
# :sort_merged_arrays DEFAULT: false
# Set to true to sort all arrays that are merged together
# :unpack_arrays DEFAULT: nil
Expand Down Expand Up @@ -59,6 +61,7 @@ class InvalidParameter < StandardError; end
def DeepMerge.deep_merge!(source, dest, options = {})
# turn on this line for stdout debugging text
merge_debug = options[:merge_debug] || false
overwrite_arrays = options[:overwrite_arrays] || false
overwrite_unmergeable = !options[:preserve_unmergeables]
knockout_prefix = options[:knockout_prefix] || nil
if knockout_prefix == ""; raise InvalidParameter, "knockout_prefix cannot be an empty string in deep_merge!"; end
Expand Down Expand Up @@ -127,7 +130,9 @@ def DeepMerge.deep_merge!(source, dest, options = {})
puts if merge_debug
end
puts "#{di} merging arrays: #{source.inspect} :: #{dest.inspect}" if merge_debug
dest = dest | source
unless overwrite_arrays
dest = dest | source
end
if sort_merged_arrays; dest.sort!; end
elsif overwrite_unmergeable
puts "#{di} overwriting dest: #{source.inspect} -over-> #{dest.inspect}" if merge_debug
Expand Down
18 changes: 18 additions & 0 deletions spec/rails_config_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,24 @@
config.inner2.inner2_inner.marshal_dump.keys.size.should eq 3
end

it "should merge arrays from multiple configs" do
config.arraylist1.size.should eq 3
config.arraylist2.inner.size.should eq 3
end
end

context "Deep Merging (old behavior)" do
let(:config) do
files = ["#{fixture_path}/deep_merge/config1.yml", "#{fixture_path}/deep_merge/config2.yml"]
RailsConfig.overwrite_arrays = false
RailsConfig.load_files(files)
end

it "should merge hashes from multiple configs" do
config.inner.marshal_dump.keys.size.should eq 3
config.inner2.inner2_inner.marshal_dump.keys.size.should eq 3
end

it "should merge arrays from multiple configs" do
config.arraylist1.size.should eq 6
config.arraylist2.inner.size.should eq 6
Expand Down

0 comments on commit d5dc9f2

Please sign in to comment.