datamapa 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/datamapa.rb +120 -0
  2. metadata +45 -0
data/lib/datamapa.rb ADDED
@@ -0,0 +1,120 @@
1
+ module DataMapa
2
+ def self.included(base)
3
+ base.extend(ClassMethods)
4
+ end
5
+
6
+ module ClassMethods
7
+ # Declarative methods
8
+ def active_record_class(klass)
9
+ @ar_class = klass
10
+ end
11
+
12
+ def model_constructor(method)
13
+ @model_constructor = method
14
+ end
15
+
16
+ def simple_attr(attributes)
17
+ @simple_attr = attributes
18
+ end
19
+
20
+ def ref_attr(attributes)
21
+ @ref_attr = attributes
22
+ end
23
+
24
+ def collection_attr(attributes)
25
+ @collection_attr = attributes
26
+ end
27
+
28
+ # Public methods
29
+ def to_ar(model, options={})
30
+ ar = model.id ? @ar_class.find(model.id) : @ar_class.new
31
+
32
+ o2r_attr(model, ar)
33
+ o2r_ref(model, ar)
34
+ o2r_collection(model, ar, options[:include]) if options[:include]
35
+
36
+ ar
37
+ end
38
+
39
+ def to_model(ar, options={})
40
+ model = @model_constructor.call
41
+
42
+ r2o_simple(ar, model)
43
+ r2o_ref(ar, model)
44
+ r2o_collection(ar, model, options[:include]) if options[:include]
45
+
46
+ model
47
+ end
48
+
49
+ def find!(id)
50
+ begin
51
+ relational = @ar_class.find(id)
52
+ to_model(relational)
53
+ rescue ActiveRecord::RecordNotFound
54
+ raise DataMapa::RecordNotFoundError
55
+ end
56
+ end
57
+
58
+ def save!(model)
59
+ begin
60
+ ar = to_ar(model)
61
+ ar.save!
62
+ model.send(:id=, ar.id)
63
+ rescue ActiveRecord::StatementInvalid
64
+ raise DataMapa::DuplicateKeyError
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def r2o_simple(relational, object)
71
+ @simple_attr.each do |attr|
72
+ setter = "#{attr.to_s.chomp('?')}="
73
+ object.send(setter, relational.send(attr))
74
+ end
75
+ end
76
+
77
+ def r2o_ref(relational, object)
78
+ @ref_attr.each do |attr, mapper|
79
+ setter = "#{attr}="
80
+ object.send(setter, mapper.to_model(relational.send(attr)))
81
+ end
82
+ end
83
+
84
+ def r2o_collection(ar, model, attributes)
85
+ attributes.each do |attr|
86
+ ar_items = ar.send(attr)
87
+ model_items = ar_items.map {|i| @collection_attr[attr].to_model(i)}
88
+ model.send("#{attr}=", model_items)
89
+ end
90
+ end
91
+
92
+ def o2r_attr(object, relational)
93
+ @simple_attr.each do |attr|
94
+ relational.send("#{attr.to_s.chomp('?')}=", object.send(attr))
95
+ end
96
+ end
97
+
98
+ def o2r_ref(object, relational)
99
+ @ref_attr.each_key do |attr|
100
+ ref = object.send(attr)
101
+ relational.send("#{attr.to_s.chomp('?')}_id=", ref.id) unless ref.nil?
102
+ end
103
+ end
104
+
105
+ def o2r_collection(object, relational, attributes)
106
+ attributes.each do |attr|
107
+ collection = object.send(attr).map do |item|
108
+ @collection_attr[attr].to_ar(item)
109
+ end
110
+ relational.send("#{attr}=", collection)
111
+ end
112
+ end
113
+ end
114
+
115
+ class RecordNotFoundError < StandardError
116
+ end
117
+
118
+ class DuplicateKeyError < StandardError
119
+ end
120
+ end
metadata ADDED
@@ -0,0 +1,45 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: datamapa
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yosuke Doi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Inverts dependency from model to persistence
15
+ email: doinchi@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/datamapa.rb
21
+ homepage: http://rubygems.org/gems/datamapa
22
+ licenses: []
23
+ post_install_message:
24
+ rdoc_options: []
25
+ require_paths:
26
+ - lib
27
+ required_ruby_version: !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ required_rubygems_version: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ requirements: []
40
+ rubyforge_project:
41
+ rubygems_version: 1.8.24
42
+ signing_key:
43
+ specification_version: 3
44
+ summary: Data Mapper using Active Record
45
+ test_files: []