summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMichael Herold <michael.j.herold@gmail.com>2018-02-05 20:10:23 -0600
committerMichael Herold <michael.j.herold@gmail.com>2018-02-06 18:42:02 -0600
commit0bd18eeb5bcbbc17d476573ae8a311fc339b6c82 (patch)
tree3d5201c99fa176c2be635cf9c2b3fa1a02a3019e /lib
parent3c6149cdd72ab8cc87cf008cc222514e30ef7470 (diff)
downloadhashie-0bd18eeb5bcbbc17d476573ae8a311fc339b6c82.tar.gz
Allow codependent Dash attributes to initialize
Definition: Codependent properties A set of two or more properties who have "required" validations that are based on each other. Example: ```ruby class OneOrMore < Hashie::Dash property :a, required: -> { b.nil? } property :b, required: -> { a.nil? } end ``` When constructing a Dash via the merge initializer, codependent properties have their "required" validation run too early when their values are set to `nil`, which causes an `ArgumentError` to be raised in the case that the first property is set to `nil`. This is an order-dependence bug that is fixed by this commit. By pruning off `nil` values only during initialization via the merge initializer, we can prevent this problem from occurring for the case of `nil` values. However, this is an indication of a larger problem with the architecture of Dash. We should be setting all the properties before running the validations. Rearchitecting this will be quite an undertaking.
Diffstat (limited to 'lib')
-rw-r--r--lib/hashie/dash.rb13
1 files changed, 11 insertions, 2 deletions
diff --git a/lib/hashie/dash.rb b/lib/hashie/dash.rb
index 4ac7676..a111e4b 100644
--- a/lib/hashie/dash.rb
+++ b/lib/hashie/dash.rb
@@ -160,7 +160,7 @@ module Hashie
end
def update_attributes!(attributes)
- initialize_attributes(attributes)
+ update_attributes(attributes)
self.class.defaults.each_pair do |prop, value|
self[prop] = begin
@@ -175,9 +175,18 @@ module Hashie
private
def initialize_attributes(attributes)
+ return unless attributes
+
+ cleaned_attributes = attributes.reject { |_attr, value| value.nil? }
+ update_attributes(cleaned_attributes)
+ end
+
+ def update_attributes(attributes)
+ return unless attributes
+
attributes.each_pair do |att, value|
self[att] = value
- end if attributes
+ end
end
def assert_property_exists!(property)