README.rdoc in ismasan-hash_mapper-0.0.2 vs README.rdoc in ismasan-hash_mapper-0.0.3

- old
+ new

@@ -29,11 +29,11 @@ :type => 'BLAH', :egg => 33 } } - ManyLevels.translate(input) + ManyLevels.normalize(input) # outputs: { :tag_id => 1, :chicken => 33, @@ -45,11 +45,11 @@ === Uses: HashMapper was primarily written as a way of mapping data structure in json requests to hashes with structures friendlier to our ActiveRecord models: - @article = Article.create( ArticleParams.translate(params[:weird_article_data]) ) + @article = Article.create( ArticleParams.normalize(params[:weird_article_data]) ) You can use HashMapper in your own little hash-like objects: class NiceHash include Enumerable @@ -57,11 +57,11 @@ map from('/names/first'), to('/first_name') map from('/names/last'), to('/last_name') def initialize(input_hash) - @hash = self.class.translate(input_hash) + @hash = self.class.normalize(input_hash) end def [](k) @hash[k] end @@ -85,15 +85,19 @@ {'one' => '1', 'two' => '2'} gets translated to {:one => 1, :two => 2} Do this: - map from('/one'), to('/one', :to_i) - map from('/two'), to('/two', :to_i) + map from('/one'), to('/one', &:to_i) + map from('/two'), to('/two', &:to_i) -You can pass :to_i, :to_s or anything available method that makes sense. +You can pass :to_i, :to_s or anything available method that makes sense. Don't forget the block notation (&). +You guessed it. That means that you can actually pass custom blocks to each to() definition as well. The following is similar to the previous example: + + map from('/one), to('/one'){|value| value.to_i} + ==== Custom value filtering You want to pass the final value of a key through a custom filter: {:names => {:first => 'Ismael', :last => 'Celis'}} gets translated to {:user => 'Mr. Celis, Ismael'} @@ -102,21 +106,24 @@ map from('/names'), to('/user') do |names| "Mr. #{names[1]}, #{names[0]}" end -==== Array access +=== Mapping in reverse -You want: +Cool, you can map one hash into another, but what if I want the opposite operation? -{:names => ['Ismael', 'Celis']} converted to {:first_name => 'Ismael', :last_name => 'Celis'} +Just use the denormalize() method instead: -Do this: - - map from('/names[0]'), to('/first_name') - map from('/names[1]'), to('/last_name') - + input = {:first => 'Mark', :last => 'Evans'} + + output = NameMapper.normalize(input) # => {:first_name => 'Mark', :last_name => 'Evans'} + + NameMapper.denormalize(output) # => input + +This will work with your block filters and even nested mappers (see below). + === Advanced usage ==== Nested mappers You want to map nested structures delegating to different mappers: @@ -143,33 +150,52 @@ class ProjectMapper extend HashMapper map from('/project'), to('/project_name') map from('/url'), to('/url') - map from('/author_names'), to('/author'), &UserMapper + map from('/author_names'), to('/author'), using(UserMapper) end Now ProjectMapper will delegate parsing of :author_names to UserMapper - ProjectMapper.translate( input ) # => output + ProjectMapper.normalize( input ) # => output * Note the ampersand in &UserMapper. This is important if you are passing custom classes instead of procs. * If you want to implement your own filter class just define to_proc in it. -Let's say you have a CompanyMapper which maps a hash with an array of employees, and you want to reuse UserMapper to map each employee: +Let's say you have a CompanyMapper which maps a hash with an array of employees, and you want to reuse UserMapper to map each employee. You could: class CompanyMapper map from('/info/name'), to('/company_name') map form('/info/address'), to('/company_address') map from('/info/year_founded'), to('year_founded', :to_i) map from('/employees'), to('employees') do |employees_array| - employees_array.collect {|emp_hash| UserMapper.translate(emp_hash)} + employees_array.collect {|emp_hash| UserMapper.normalize(emp_hash)} end end +But HashMapper's nested mappers will actually do that for you if a value is an array, so: + + map from('/employees'), to('employees'), using(UserMapper) + +... Will map each employee using UserMapper. + == REQUIREMENTS: +== TODO: +=== Array access + +* See pending specs + +You want: + +{:names => ['Ismael', 'Celis']} converted to {:first_name => 'Ismael', :last_name => 'Celis'} + +Do this: + + map from('/names[0]'), to('/first_name') + map from('/names[1]'), to('/last_name') == INSTALL: # If you haven't done this already: \ No newline at end of file