Added IgnoreUndeclared, an extension to silently ignore undeclared properties at hash intialization.

This commit is contained in:
Michael Righi 2014-04-06 09:28:22 -04:00 committed by dblock
parent 75e67454e4
commit 736fd08892
5 changed files with 92 additions and 0 deletions

View File

@ -4,6 +4,7 @@
* Removed support for Ruby 1.8.7 - [@dblock](https://github.com/dblock).
* Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
* [#138](https://github.com/intridea/hashie/pull/138): Added Hashie#Rash, a hash whose keys can be regular expressions or ranges - [@epitron](https://github.com/epitron).
* [#131](https://github.com/intridea/hashie/pull/131): Added IgnoreUndeclared, an extension to silently ignore undeclared properties at intialization - [@righi](https://github.com/righi).
* [#136](https://github.com/intridea/hashie/issues/136): Removed Hashie::Extensions::Structure - [@markiz](https://github.com/markiz).
* [#107](https://github.com/intridea/hashie/pull/107): Fixed excessive value conversions, poor performance of deep merge in Hashie::Mash - [@davemitchell](https://github.com/dblock), [@dblock](https://github.com/dblock).
* [#69](https://github.com/intridea/hashie/issues/69): Fixed assigning multiple properties in Hashie::Trash - [@einzige](https://github.com/einzige).

View File

@ -101,6 +101,32 @@ hash in question. This means you can safely merge together indifferent
and non-indifferent hashes arbitrarily deeply without worrying about
whether you'll be able to `hash[:other][:another]` properly.
### IgnoreUndeclared
This extension can be mixed in to silently ignore undeclared properties on
initialization instead of raising an error. This is useful when using a
Trash to capture a subset of a larger hash.
```ruby
class Person < Trash
include Hashie::Extensions::IgnoreUndeclared
property :first_name
property :last_name
end
user_data = {
first_name: 'Freddy',
last_name: 'Nostrils',
email: 'freddy@example.com'
}
p = Person.new(user_data) # 'email' is silently ignored
p.first_name # => 'Freddy'
p.last_name # => 'Nostrils'
p.email # => NoMethodError
```
### DeepMerge
This extension allow you to easily include a recursive merging

View File

@ -12,6 +12,7 @@ module Hashie
autoload :Coercion, 'hashie/extensions/coercion'
autoload :DeepMerge, 'hashie/extensions/deep_merge'
autoload :KeyConversion, 'hashie/extensions/key_conversion'
autoload :IgnoreUndeclared, 'hashie/extensions/ignore_undeclared'
autoload :IndifferentAccess, 'hashie/extensions/indifferent_access'
autoload :MergeInitializer, 'hashie/extensions/merge_initializer'
autoload :MethodAccess, 'hashie/extensions/method_access'

View File

@ -0,0 +1,41 @@
module Hashie
module Extensions
# IgnoreUndeclared is a simple mixin that silently ignores
# undeclared properties on initialization instead of
# raising an error. This is useful when using a Trash to
# capture a subset of a larger hash.
#
# Note that attempting to retrieve an undeclared property
# will still raise a NoMethodError, even if a value for
# that property was provided at initialization.
#
# @example
# class Person < Trash
# include Hashie::Extensions::IgnoreUndeclared
#
# property :first_name
# property :last_name
# end
#
# user_data = {
# :first_name => 'Freddy',
# :last_name => 'Nostrils',
# :email => 'freddy@example.com'
# }
#
# p = Person.new(user_data) # 'email' is silently ignored
#
# p.first_name # => 'Freddy'
# p.last_name # => 'Nostrils'
# p.email # => NoMethodError
module IgnoreUndeclared
def initialize_attributes(attributes)
attributes.each_pair do |att, value|
if self.class.property?(att) || (self.class.respond_to?(:translations) && self.class.translations.include?(att.to_sym))
self[att] = value
end
end if attributes
end
end
end
end

View File

@ -0,0 +1,23 @@
require 'spec_helper'
describe Hashie::Extensions::IgnoreUndeclared do
class ForgivingTrash < Hashie::Trash
include Hashie::Extensions::IgnoreUndeclared
property :city
property :state, from: :provence
end
subject { ForgivingTrash }
it 'should silently ignore undeclared properties on initialization' do
expect { subject.new(city: 'Toronto', provence: 'ON', country: 'Canada') }.to_not raise_error
end
it 'should work with translated properties (with symbol keys)' do
expect(subject.new(provence: 'Ontario').state).to eq('Ontario')
end
it 'should work with translated properties (with string keys)' do
expect(subject.new(provence: 'Ontario').state).to eq('Ontario')
end
end