summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Herold <michael.j.herold+github@gmail.com>2014-08-24 12:03:32 -0500
committerMichael Herold <michael.j.herold+github@gmail.com>2014-08-24 12:03:32 -0500
commit976c689632ea0d9538cfa840e5f777d2f3d054c8 (patch)
treeef8b27c22c2d01aef97676642dc11d53a4bce1d7
parent65dd4496ea86d0a71b190a58038d1955f19ba84a (diff)
parent57a0ffb6786057af0129ecc0a0ea06ad4be9c9e6 (diff)
downloadhashie-976c689632ea0d9538cfa840e5f777d2f3d054c8.tar.gz
Merge pull request #212 from dblock/69-multiple-properties-in-trash
Fix #69: multiple property assignments in Trash.
-rw-r--r--CHANGELOG.md1
-rw-r--r--lib/hashie/trash.rb38
-rw-r--r--spec/hashie/trash_spec.rb25
3 files changed, 54 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e0e33a4..717a756 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@
* [#206](http://github.com/intridea/hashie/pull/206): Fixed stack overflow from repetitively including coercion in subclasses - [@michaelherold](https://github.com/michaelherold).
* [#207](http://github.com/intridea/hashie/pull/207): Fixed inheritance of transformations in Trash - [@fobocaster](https://github.com/fobocaster).
* [#209](http://github.com/intridea/hashie/pull/209): Added Hashie::Extensions::DeepFind - [@michaelherold](https://github.com/michaelherold).
+* [#69](https://github.com/intridea/hashie/pull/69): Fixed regression in assigning multiple properties in Hashie::Trash - [@michaelherold](https://github.com/michaelherold), [@einzige](https://github.com/einzige), [@dblock](https://github.com/dblock).
* Your contribution here.
## 3.2.0 (7/10/2014)
diff --git a/lib/hashie/trash.rb b/lib/hashie/trash.rb
index 204b0d7..dbf4dae 100644
--- a/lib/hashie/trash.rb
+++ b/lib/hashie/trash.rb
@@ -26,11 +26,13 @@ module Hashie
fail ArgumentError, "Property name (#{property_name}) and :from option must not be the same"
end
- translations[options[:from]] = property_name
+ translations_hash[options[:from]] ||= {}
+ translations_hash[options[:from]][property_name] = options[:with] || options[:transform_with]
define_method "#{options[:from]}=" do |val|
- with = options[:with] || options[:transform_with]
- self[property_name] = with.respond_to?(:call) ? with.call(val) : val
+ self.class.translations_hash[options[:from]].each do |name, with|
+ self[name] = with.respond_to?(:call) ? with.call(val) : val
+ end
end
else
if options[:transform_with].respond_to? :call
@@ -40,15 +42,15 @@ module Hashie
end
class << self
- attr_reader :transforms, :translations
+ attr_reader :transforms, :translations_hash
end
instance_variable_set('@transforms', {})
- instance_variable_set('@translations', {})
+ instance_variable_set('@translations_hash', {})
def self.inherited(klass)
super
klass.instance_variable_set('@transforms', transforms.dup)
- klass.instance_variable_set('@translations', translations.dup)
+ klass.instance_variable_set('@translations_hash', translations_hash.dup)
end
# Set a value on the Dash in a Hash-like way. Only works
@@ -68,7 +70,7 @@ module Hashie
end
def self.translation_exists?(name)
- translations.key? name
+ translations_hash.key? name
end
def self.transformation_exists?(name)
@@ -81,8 +83,26 @@ module Hashie
private
+ def self.translations
+ @translations ||= begin
+ h = {}
+ translations_hash.each do |(property_name, property_translations)|
+ h[property_name] = property_translations.size > 1 ? property_translations.keys : property_translations.keys.first
+ end
+ h
+ end
+ end
+
def self.inverse_translations
- @inverse_translations ||= Hash[translations.map(&:reverse)]
+ @inverse_translations ||= begin
+ h = {}
+ translations_hash.each do |(property_name, property_translations)|
+ property_translations.keys.each do |k|
+ h[k] = property_name
+ end
+ end
+ h
+ end
end
# Raises an NoMethodError if the property doesn't exist
@@ -98,7 +118,7 @@ module Hashie
def initialize_attributes(attributes)
return unless attributes
attributes_copy = attributes.dup.delete_if do |k, v|
- if self.class.translations.include?(k)
+ if self.class.translations_hash.include?(k)
self[k] = v
true
end
diff --git a/spec/hashie/trash_spec.rb b/spec/hashie/trash_spec.rb
index e844093..7bb174f 100644
--- a/spec/hashie/trash_spec.rb
+++ b/spec/hashie/trash_spec.rb
@@ -29,7 +29,7 @@ describe Hashie::Trash do
end
it 'maintains translations hash mapping from the original to the translated name' do
- expect(TrashTest.translations[:firstName]).to eq :first_name
+ expect(TrashTest.translations[:firstName]).to eq(:first_name)
end
it 'maintains inverse translations hash mapping from the translated to the original name' do
@@ -134,6 +134,29 @@ describe Hashie::Trash do
end
end
+ describe 'translating multiple properties using a proc' do
+ class SomeDataModel < Hashie::Trash
+ property :value_a, from: :config, with: ->(config) { config.a }
+ property :value_b, from: :config, with: ->(config) { config.b }
+ end
+
+ ConfigDataModel = Struct.new(:a, :b)
+
+ subject { SomeDataModel.new(config: ConfigDataModel.new('value in a', 'value in b')) }
+
+ it 'translates the first key' do
+ expect(subject.value_a).to eq 'value in a'
+ end
+
+ it 'translates the second key' do
+ expect(subject.value_b).to eq 'value in b'
+ end
+
+ it 'maintains translations hash mapping from the original to the translated name' do
+ expect(SomeDataModel.translations).to eq(config: [:value_a, :value_b])
+ end
+ end
+
describe 'uses with or transform_with interchangeably' do
class TrashLambdaTestTransformWith < Hashie::Trash
property :first_name, from: :firstName, transform_with: ->(value) { value.reverse }