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