Skip to content
This repository was archived by the owner on Apr 18, 2018. It is now read-only.

Commit 0012233

Browse files
committed
Add a mapping API to the repository.
1 parent 38de9af commit 0012233

File tree

5 files changed

+115
-2
lines changed

5 files changed

+115
-2
lines changed

lib/curator.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
require 'rubygems'
22

3+
require 'curator/mapper'
34
require 'curator/migration'
45
require 'curator/migrator'
56
require 'curator/model'

lib/curator/mapper.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module Curator
2+
class Mapper
3+
def initialize(field_name, options)
4+
@field_name = field_name
5+
@serialize_function = options[:serialize]
6+
@deserialize_function = options[:deserialize]
7+
end
8+
9+
def deserialize(attributes)
10+
_map(attributes, @deserialize_function)
11+
end
12+
13+
def serialize(attributes)
14+
_map(attributes, @serialize_function)
15+
end
16+
17+
def _map(attributes, mapping_function)
18+
current_value = attributes[@field_name]
19+
if current_value && mapping_function
20+
mapped_value = mapping_function.call(current_value)
21+
attributes.merge(@field_name => mapped_value)
22+
else
23+
attributes
24+
end
25+
end
26+
end
27+
end

lib/curator/repository.rb

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ def klass
5555
name.to_s.gsub("Repository", "").constantize
5656
end
5757

58+
def map(field_name, options)
59+
_mappers << Mapper.new(field_name, options)
60+
end
61+
62+
def _mappers
63+
@mappers ||= []
64+
end
65+
5866
def migrator
5967
@migrator ||= Curator::Migrator.new(collection_name)
6068
end
@@ -82,7 +90,8 @@ def save_without_timestamps(object)
8290
end
8391

8492
def serialize(object)
85-
object.instance_values
93+
attributes = object.instance_values.with_indifferent_access
94+
_mappers.inject(attributes) { |attrs, mapper| mapper.serialize(attrs) }
8695
end
8796

8897
def _build_finder_methods(field_name)
@@ -106,7 +115,8 @@ def _find_by_index(collection_name, field_name, value)
106115
end
107116

108117
def deserialize(attributes)
109-
klass.new(attributes)
118+
mapped_attributes = _mappers.inject(attributes) { |attrs, mapper| mapper.deserialize(attrs) }
119+
klass.new(mapped_attributes)
110120
end
111121

112122
def _deserialize(id, data)

spec/curator/mapper_spec.rb

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
require 'spec_helper'
2+
3+
describe Curator::Mapper do
4+
describe "serialize" do
5+
it "serializes a field" do
6+
mapper = Curator::Mapper.new(:foo, :serialize => lambda { |v| v + 1 })
7+
mapper.serialize(:foo => 1).should == {:foo => 2}
8+
end
9+
10+
it "ignores other fields" do
11+
mapper = Curator::Mapper.new(:foo, :serialize => lambda { |v| v + 1 })
12+
mapper.serialize(:bar => 1).should == {:bar => 1}
13+
end
14+
15+
it "leaves fields alone if there is no option" do
16+
mapper = Curator::Mapper.new(:foo, {})
17+
mapper.serialize(:foo => 1).should == {:foo => 1}
18+
end
19+
end
20+
21+
describe "deserialize" do
22+
it "deserializes a field" do
23+
mapper = Curator::Mapper.new(:foo, :deserialize => lambda { |v| v + 1 })
24+
mapper.deserialize(:foo => 1).should == {:foo => 2}
25+
end
26+
27+
it "ignores other fields" do
28+
mapper = Curator::Mapper.new(:foo, :deserialize => lambda { |v| v + 1 })
29+
mapper.deserialize(:bar => 1).should == {:bar => 1}
30+
end
31+
32+
it "leaves fields alone if there is no option" do
33+
mapper = Curator::Mapper.new(:foo, {})
34+
mapper.deserialize(:foo => 1).should == {:foo => 1}
35+
end
36+
end
37+
end

spec/curator/repository_spec.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,42 @@ def migrate(hash)
306306
repository.save_without_timestamps(model).should == model
307307
end
308308
end
309+
310+
describe "mapping" do
311+
it "runs serialize and deserialize" do
312+
repository = test_repository do
313+
map :some_field, :serialize => lambda { |i| (i + 1).to_s }, :deserialize => lambda { |str| "5#{str}".to_i }
314+
end
315+
316+
model = TestModel.new(:some_field => 3)
317+
repository.save(model)
318+
319+
found_model = repository.find_by_id(model.id)
320+
found_model.some_field.should == 54
321+
end
322+
323+
it "does not change value when no serialize is specified" do
324+
repository = test_repository do
325+
map :some_field, :deserialize => lambda { |str| Date.parse(str) }
326+
end
327+
328+
model = TestModel.new(:some_field => Date.today)
329+
repository.save(model)
330+
331+
found_model = repository.find_by_id(model.id)
332+
found_model.some_field.should == Date.today
333+
end
334+
335+
it "leaves value as is when no deserialize is specified" do
336+
repository = test_repository do
337+
map :some_field, :serialize => lambda { |date| date.year }
338+
end
339+
340+
model = TestModel.new(:some_field => Date.today)
341+
repository.save(model)
342+
343+
found_model = repository.find_by_id(model.id)
344+
found_model.some_field.should == Date.today.year
345+
end
346+
end
309347
end

0 commit comments

Comments
 (0)