datamapa 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/datamapa.rb +120 -0
- 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: []
|