vorpal 0.0.6.rc2 → 0.0.6.rc3

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjNjZWQxNmI3MGUyNDY3ZGM1MTFlNzVlMTRhNTMwMjZkNDczNWIzNg==
4
+ NDJjYTFiMjk0N2U4NmYxYjI4NGIwMmY0N2VkOWZiYjRjZjI4OTFlOA==
5
5
  data.tar.gz: !binary |-
6
- MDNmMmQ5OWZjNjQ3NGY5ZWY4ZDg1NzkwMGQyMWJhZThkYjBlMGY0ZQ==
6
+ OWJjZDM0Y2JiMGIzNGNlY2MxOWFmNDQwYWUyZTRiMDJiNDBkNmZmYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OGU3YWE5MDdkYmY4NjIwMDA2ZDY5YWIwNGY1NzdkNjIyYzY0YzQ3ZGUwNDY5
10
- ZmI5NGYyYjRlYzU4NWY2NTk1ZmY5NWQ5ODVhNzEwODJjY2I3YzZmZmE4ODg0
11
- N2RmNGNkNjAzODIxZGIwN2NiYzcyZGE5MTM4ZmI5NDZiYjM4OWQ=
9
+ NmU3YTQ2OGNkYzZjNTM3ODMxODc5NjlhZjFhOWFlMmNkMjRmMzg1NGE0ZGRm
10
+ MGY3MWRlZjM0ZjFlOWFhNzI0N2Q2MzMwODMyYzFkODJlMzExZjBmZTAzNGE0
11
+ NmUzODFkMWU3M2IzN2NhODA3YzZhMDU1OTllZjEyNzJlY2Q0ODI=
12
12
  data.tar.gz: !binary |-
13
- NDBjMzIzYTcwYmQyMzI2MDM2ZmJjYjY4NmUzNWU0NjhiYzVkMDkyYTA0Y2M4
14
- OTQ2OTYyOWUxYWE2MDg1ZGI0MzUxNjYyMzEyMDJhZjNlNzk3MDIzMTVmMWEx
15
- ZTc3YTg5MzAyNDMyNzEwMDc1NzY3N2I0YTJlMzJhNGRiNmNhOWY=
13
+ MWY5NzQ0N2Q2NjE5NDI4MmE4MzRmMDM4ZjI3M2M4NjQ1MTBhYzA4MWY3YTJm
14
+ YmQxNDI2MTcwOWRkYmRlNjcwYTNiN2E4N2I1ZWU4ZmZiYTZkMWU1ZDE2NmZh
15
+ NjA0OWJmMDg2Y2M4NDYzYzVhNjg5MTE0YTAzMTg4NDkzOTNmNTQ=
@@ -6,8 +6,9 @@ require 'vorpal/db_driver'
6
6
  module Vorpal
7
7
  class AggregateRepository
8
8
  # @private
9
- def initialize(class_configs)
10
- configure(class_configs)
9
+ def initialize(db_driver, master_config)
10
+ @db_driver = db_driver
11
+ @configs = master_config
11
12
  end
12
13
 
13
14
  # Saves an aggregate to the DB. Inserts objects that are new to the
@@ -76,11 +77,11 @@ class AggregateRepository
76
77
  # operation.
77
78
  # @return [[Object]] Entities with the given primary key values and type.
78
79
  def load_all(ids, domain_class, identity_map=IdentityMap.new)
79
- db_objects = load_from_db(ids, domain_class).all_objects
80
- deserialize(db_objects, identity_map)
81
- set_associations(db_objects, identity_map)
80
+ loaded_db_objects = load_from_db(ids, domain_class)
81
+ objects = deserialize(loaded_db_objects, identity_map)
82
+ set_associations(loaded_db_objects, identity_map)
82
83
 
83
- identity_map.map_raw(ids, @configs.config_for(domain_class).db_class)
84
+ objects.select { |obj| obj.class == domain_class }
84
85
  end
85
86
 
86
87
  # Removes an aggregate from the DB. Even if the aggregate contains unsaved
@@ -101,7 +102,7 @@ class AggregateRepository
101
102
  return roots if roots.empty?
102
103
  loaded_db_objects = load_owned_from_db(roots.map(&:id), roots.first.class)
103
104
  loaded_db_objects.each do |config, db_objects|
104
- DbDriver.destroy(config, db_objects)
105
+ @db_driver.destroy(config.db_class, db_objects)
105
106
  end
106
107
  roots
107
108
  end
@@ -113,62 +114,36 @@ class AggregateRepository
113
114
  end
114
115
 
115
116
  def load_from_db(ids, domain_class, only_owned=false)
116
- DbLoader.new(@configs, only_owned).load_from_db(ids, domain_class)
117
+ DbLoader.new(@configs, only_owned, @db_driver).load_from_db(ids, domain_class)
117
118
  end
118
119
 
119
120
  def load_owned_from_db(ids, domain_class)
120
121
  load_from_db(ids, domain_class, true)
121
122
  end
122
123
 
123
- def deserialize(db_objects, identity_map)
124
- db_objects.each do |db_object|
125
- # TODO: There is probably a bug here when you have something in the IdentityMap that is stale.
126
- identity_map.get_and_set(db_object) { @configs.config_for_db(db_object.class).deserialize(db_object) }
127
- end
128
- end
129
-
130
- def set_associations(db_objects, identity_map)
131
- db_objects.each do |db_object|
132
- config = @configs.config_for_db(db_object.class)
133
- config.has_manys.each do |has_many_config|
134
- db_children = find_associated(db_object, has_many_config, db_objects)
135
- associate_one_to_many(db_object, db_children, has_many_config, identity_map)
136
- end
137
-
138
- config.has_ones.each do |has_one_config|
139
- db_children = find_associated(db_object, has_one_config, db_objects)
140
- associate_one_to_one(db_object, db_children.first, has_one_config, identity_map)
141
- end
142
-
143
- config.belongs_tos.each do |belongs_to_config|
144
- db_children = find_associated(db_object, belongs_to_config, db_objects)
145
- associate_one_to_one(db_object, db_children.first, belongs_to_config, identity_map)
124
+ def deserialize(loaded_db_objects, identity_map)
125
+ loaded_db_objects.flat_map do |config, db_objects|
126
+ db_objects.map do |db_object|
127
+ # TODO: There is a bug here when you have something in the IdentityMap that is stale and needs to be updated.
128
+ identity_map.get_and_set(db_object) { config.deserialize(db_object) }
146
129
  end
147
130
  end
148
131
  end
149
132
 
150
- def find_associated(db_object, association_config, db_objects)
151
- db_objects.find_all do |db_child|
152
- association_config.associated?(db_object, db_child)
133
+ def set_associations(loaded_db_objects, identity_map)
134
+ loaded_db_objects.each do |config, db_objects|
135
+ db_objects.each do |db_object|
136
+ config.local_association_configs.each do |association_config|
137
+ db_remote = loaded_db_objects.find_by_id(
138
+ association_config.remote_class_config(db_object),
139
+ association_config.fk_value(db_object)
140
+ )
141
+ association_config.associate(identity_map.get(db_object), identity_map.get(db_remote))
142
+ end
143
+ end
153
144
  end
154
145
  end
155
146
 
156
- def associate_one_to_many(db_object, db_children, one_to_many, identity_map)
157
- parent = identity_map.get(db_object)
158
- children = identity_map.map(db_children)
159
- one_to_many.set_children(parent, children)
160
- end
161
-
162
- def associate_one_to_one(db_parent, db_child, one_to_one_config, identity_map)
163
- parent = identity_map.get(db_parent)
164
- child = identity_map.get(db_child)
165
- one_to_one_config.set_child(parent, child)
166
- end
167
-
168
- def configure(class_configs)
169
- @configs = MasterConfig.new(class_configs)
170
- end
171
-
172
147
  def serialize(owned_objects, mapping, loaded_db_objects)
173
148
  owned_objects.each do |config, objects|
174
149
  objects.each do |object|
@@ -184,7 +159,7 @@ class AggregateRepository
184
159
  if object.id.nil?
185
160
  config.build_db_object(attributes)
186
161
  else
187
- db_object = loaded_db_objects.find_by_id(object, config)
162
+ db_object = loaded_db_objects.find_by_id(config, object.id)
188
163
  config.set_db_object_attributes(db_object, attributes)
189
164
  db_object
190
165
  end
@@ -196,7 +171,7 @@ class AggregateRepository
196
171
  def set_primary_keys(owned_objects, mapping)
197
172
  owned_objects.each do |config, objects|
198
173
  in_need_of_primary_keys = objects.find_all { |obj| obj.id.nil? }
199
- primary_keys = DbDriver.get_primary_keys(config, in_need_of_primary_keys.length)
174
+ primary_keys = @db_driver.get_primary_keys(config.db_class, in_need_of_primary_keys.length)
200
175
  in_need_of_primary_keys.zip(primary_keys).each do |object, primary_key|
201
176
  mapping[object].id = primary_key
202
177
  object.id = primary_key
@@ -237,11 +212,11 @@ class AggregateRepository
237
212
  owned_objects.each do |config, objects|
238
213
  objects_to_insert = grouped_new_objects[config] || []
239
214
  db_objects_to_insert = objects_to_insert.map { |obj| mapping[obj] }
240
- DbDriver.insert(config, db_objects_to_insert)
215
+ @db_driver.insert(config.db_class, db_objects_to_insert)
241
216
 
242
217
  objects_to_update = objects - objects_to_insert
243
218
  db_objects_to_update = objects_to_update.map { |obj| mapping[obj] }
244
- DbDriver.update(config, db_objects_to_update)
219
+ @db_driver.update(config.db_class, db_objects_to_update)
245
220
  end
246
221
  end
247
222
 
@@ -249,9 +224,9 @@ class AggregateRepository
249
224
  db_objects_in_aggregate = mapping.values
250
225
  db_objects_in_db = loaded_db_objects.all_objects
251
226
  all_orphans = db_objects_in_db - db_objects_in_aggregate
252
- grouped_orphans = all_orphans.group_by { |o| @configs.config_for_db(o.class) }
227
+ grouped_orphans = all_orphans.group_by { |o| @configs.config_for_db_object(o) }
253
228
  grouped_orphans.each do |config, orphans|
254
- DbDriver.destroy(config, orphans)
229
+ @db_driver.destroy(config.db_class, orphans)
255
230
  end
256
231
  end
257
232
 
@@ -2,268 +2,278 @@ require 'vorpal/util/hash_initialization'
2
2
  require 'equalizer'
3
3
 
4
4
  module Vorpal
5
+ # @private
6
+ class MasterConfig
7
+ def initialize(class_configs)
8
+ @class_configs = class_configs
9
+ initialize_association_configs
10
+ end
5
11
 
6
- # @private
7
- class MasterConfig
8
- def initialize(class_configs)
9
- @class_configs = class_configs
10
- initialize_association_configs
11
- end
12
-
13
- def config_for(clazz)
14
- @class_configs.detect { |conf| conf.domain_class == clazz }
15
- end
12
+ def config_for(clazz)
13
+ @class_configs.detect { |conf| conf.domain_class == clazz }
14
+ end
16
15
 
17
- def config_for_db(clazz)
18
- @class_configs.detect { |conf| conf.db_class == clazz }
19
- end
16
+ def config_for_db_object(db_object)
17
+ @class_configs.detect { |conf| conf.db_class == db_object.class }
18
+ end
20
19
 
21
- private
20
+ private
21
+
22
+ def initialize_association_configs
23
+ association_configs = {}
24
+ @class_configs.each do |config|
25
+ (config.has_ones + config.has_manys).each do |association_end_config|
26
+ child_config = config_for(association_end_config.child_class)
27
+ association_end_config.set_parent_class_config(config)
28
+
29
+ association_config = build_association_config(association_configs, child_config, association_end_config.fk, association_end_config.fk_type)
30
+ association_config.remote_end_config = association_end_config
31
+ association_config.add_remote_class_config(config)
32
+ association_end_config.association_config = association_config
33
+ end
34
+
35
+ config.belongs_tos.each do |association_end_config|
36
+ child_configs = association_end_config.child_classes.map(&method(:config_for))
37
+
38
+ association_config = build_association_config(association_configs, config, association_end_config.fk, association_end_config.fk_type)
39
+ association_config.local_end_config = association_end_config
40
+ association_config.add_remote_class_config(child_configs)
41
+ association_end_config.association_config = association_config
42
+ end
43
+ end
22
44
 
23
- def initialize_association_configs
24
- @class_configs.each do |config|
25
- (config.has_ones + config.has_manys).each do |association_config|
26
- association_config.init_relational_association(
27
- config_for(association_config.child_class),
28
- config
29
- )
45
+ association_configs.values.each do |association_config|
46
+ association_config.local_class_config.local_association_configs << association_config
30
47
  end
31
- config.belongs_tos.each do |association_config|
32
- association_config.init_relational_association(
33
- association_config.child_classes.map(&method(:config_for)),
34
- config
35
- )
48
+ end
49
+
50
+ def build_association_config(association_configs, local_config, fk, fk_type)
51
+ association_config = AssociationConfig.new(local_config, fk, fk_type)
52
+ if association_configs[association_config]
53
+ association_config = association_configs[association_config]
54
+ else
55
+ association_configs[association_config] = association_config
36
56
  end
57
+ association_config
37
58
  end
38
59
  end
39
- end
40
-
41
- # @private
42
- class ClassConfig
43
- include Equalizer.new(:domain_class, :db_class)
44
- attr_reader :serializer, :deserializer, :domain_class, :db_class
45
- attr_accessor :has_manys, :belongs_tos, :has_ones
46
60
 
47
- def initialize(attrs)
48
- @has_manys = []
49
- @belongs_tos = []
50
- @has_ones = []
51
-
52
- attrs.each do |k,v|
53
- instance_variable_set("@#{k}", v)
61
+ # @private
62
+ # Object associations:
63
+ # - All object associations are uni-directional
64
+ # - The end that holds the association is the 'Parent' and the end that
65
+ # is referred to is the 'Child' or 'Children'
66
+ #
67
+ # Relational associations:
68
+ # - Local end: has FK
69
+ # - Remote end: has no FK
70
+ #
71
+ class AssociationConfig
72
+ include Equalizer.new(:local_class_config, :fk)
73
+
74
+ attr_reader :local_class_config, :remote_class_configs, :fk
75
+
76
+ # Only one of these two fields needs to be specified
77
+ # If one is specified, then the association is uni-directional.
78
+ # If both are specified, then the association is bi-directional.
79
+ attr_accessor :local_end_config, :remote_end_config
80
+
81
+ def initialize(local_class_config, fk, fk_type)
82
+ @local_class_config = local_class_config
83
+ @remote_class_configs = {}
84
+ @fk = fk
85
+ @fk_type = fk_type
54
86
  end
55
- end
56
87
 
57
- def build_db_object(attributes)
58
- db_class.new(attributes)
59
- end
88
+ def fk_value(local_db_object)
89
+ local_db_object.send(fk)
90
+ end
60
91
 
61
- def set_db_object_attributes(db_object, attributes)
62
- db_object.attributes = attributes
63
- end
92
+ def associate(local_object, remote_object)
93
+ local_end_config.associate(local_object, remote_object) if local_end_config && local_object
94
+ remote_end_config.associate(remote_object, local_object) if remote_end_config && remote_object
95
+ end
64
96
 
65
- def get_db_object_attributes(db_object)
66
- db_object.attributes.symbolize_keys
67
- end
97
+ def add_remote_class_config(remote_class_configs)
98
+ Array(remote_class_configs).each do |remote_class_config|
99
+ @remote_class_configs[remote_class_config.domain_class.name] = remote_class_config
100
+ end
101
+ end
68
102
 
69
- def serialization_required?
70
- !(domain_class < ActiveRecord::Base)
71
- end
103
+ def remote_class_config(local_db_object)
104
+ if polymorphic?
105
+ fk_type_value = local_db_object.send(@fk_type)
106
+ @remote_class_configs[fk_type_value]
107
+ else
108
+ @remote_class_configs.values.first
109
+ end
110
+ end
72
111
 
73
- def serialize(object)
74
- serializer.serialize(object)
75
- end
112
+ def polymorphic?
113
+ !@fk_type.nil?
114
+ end
76
115
 
77
- def deserialize(db_object)
78
- attributes = get_db_object_attributes(db_object)
79
- serialization_required? ? deserializer.deserialize(domain_class.new, attributes) : db_object
80
- end
116
+ def set_foreign_key(local_db_object, remote_object)
117
+ local_class_config.set_field(local_db_object, @fk, remote_object.try(:id))
118
+ local_class_config.set_field(local_db_object, @fk_type, remote_object.class.name) if polymorphic?
119
+ end
81
120
 
82
- def set_field(db_object, field, value)
83
- db_object.send("#{field}=", value)
121
+ def foreign_key_info(remote_class_config)
122
+ ForeignKeyInfo.new(@fk, @fk_type, remote_class_config.domain_class.name, polymorphic?)
123
+ end
84
124
  end
85
125
 
86
- def get_field(db_object, field)
87
- db_object.send(field)
88
- end
126
+ # @private
127
+ class ClassConfig
128
+ include Equalizer.new(:domain_class, :db_class)
129
+ attr_reader :serializer, :deserializer, :domain_class, :db_class, :local_association_configs
130
+ attr_accessor :has_manys, :belongs_tos, :has_ones
89
131
 
90
- def table_name
91
- db_class.table_name
92
- end
93
- end
132
+ def initialize(attrs)
133
+ @has_manys = []
134
+ @belongs_tos = []
135
+ @has_ones = []
136
+ @local_association_configs = []
94
137
 
95
- # @private
96
- class ForeignKeyInfo
97
- include Equalizer.new(:fk_column, :fk_type_column, :fk_type)
138
+ attrs.each do |k,v|
139
+ instance_variable_set("@#{k}", v)
140
+ end
141
+ end
98
142
 
99
- attr_reader :fk_column, :fk_type_column, :fk_type, :polymorphic
143
+ def build_db_object(attributes)
144
+ db_class.new(attributes)
145
+ end
100
146
 
101
- def initialize(fk_column, fk_type_column, fk_type, polymorphic)
102
- @fk_column = fk_column
103
- @fk_type_column = fk_type_column
104
- @fk_type = fk_type
105
- @polymorphic = polymorphic
106
- end
147
+ def set_db_object_attributes(db_object, attributes)
148
+ db_object.attributes = attributes
149
+ end
107
150
 
108
- def polymorphic?
109
- @polymorphic
110
- end
151
+ def get_db_object_attributes(db_object)
152
+ db_object.attributes.symbolize_keys
153
+ end
111
154
 
112
- def matches_polymorphic_type?(db_object)
113
- db_object.send(fk_type_column) == fk_type
114
- end
115
- end
155
+ def serialization_required?
156
+ !(domain_class < ActiveRecord::Base)
157
+ end
116
158
 
117
- # @private
118
- # Object associations:
119
- # - All object associations are uni-directional
120
- # - The end that holds the association is the 'Parent' and the end that
121
- # is referred to is the 'Child' or 'Children'
122
- #
123
- # Relational associations:
124
- # - Local end: has FK
125
- # - Remote end: has no FK
126
- #
127
- class RelationalAssociation
128
- include HashInitialization
129
- attr_reader :fk, :fk_type, :local_config, :remote_configs
130
-
131
- # Can't pass in a remote db model for last param because when saving we only have
132
- # a db model if the model is part of the aggregate and not just referenced by the
133
- # aggregate
134
- def set_foreign_key(local_db_model, remote_model)
135
- local_config.set_field(local_db_model, fk, remote_model.try(:id))
136
- local_config.set_field(local_db_model, fk_type, remote_model.class.name) if polymorphic?
137
- end
159
+ def serialize(object)
160
+ serializer.serialize(object)
161
+ end
138
162
 
139
- def remote_config_for_local_db_object(local_db_model)
140
- class_name = local_config.get_field(local_db_model, fk_type)
141
- remote_configs.detect { |config| config.domain_class.name == class_name }
142
- end
163
+ def deserialize(db_object)
164
+ attributes = get_db_object_attributes(db_object)
165
+ serialization_required? ? deserializer.deserialize(domain_class.new, attributes) : db_object
166
+ end
143
167
 
144
- def polymorphic?
145
- !fk_type.nil?
146
- end
168
+ def set_field(db_object, field, value)
169
+ db_object.send("#{field}=", value)
170
+ end
147
171
 
148
- def foreign_key_info(remote_class_config)
149
- ForeignKeyInfo.new(fk, fk_type, remote_class_config.domain_class.name, polymorphic?)
172
+ def get_field(db_object, field)
173
+ db_object.send(field)
174
+ end
150
175
  end
151
176
 
152
- private
177
+ # @private
178
+ class ForeignKeyInfo
179
+ include Equalizer.new(:fk_column, :fk_type_column, :fk_type)
153
180
 
154
- def get_foreign_key(local_db_model)
155
- local_config.get_field(local_db_model, fk)
156
- end
157
- end
181
+ attr_reader :fk_column, :fk_type_column, :fk_type, :polymorphic
158
182
 
159
- # @private
160
- class HasManyConfig
161
- include HashInitialization
162
- attr_reader :name, :owned, :fk, :fk_type, :child_class
183
+ def initialize(fk_column, fk_type_column, fk_type, polymorphic)
184
+ @fk_column = fk_column
185
+ @fk_type_column = fk_type_column
186
+ @fk_type = fk_type
187
+ @polymorphic = polymorphic
188
+ end
163
189
 
164
- def init_relational_association(child_config, parent_config)
165
- @parent_config = parent_config
166
- @relational_association = RelationalAssociation.new(fk: fk, fk_type: fk_type, local_config: child_config, remote_configs: [parent_config])
190
+ def polymorphic?
191
+ @polymorphic
192
+ end
167
193
  end
168
194
 
169
- def get_children(parent)
170
- parent.send(name)
171
- end
195
+ module RemoteEndConfig
196
+ def child_config
197
+ association_config.local_class_config
198
+ end
172
199
 
173
- def set_children(parent, children)
174
- parent.send("#{name}=", children)
175
- end
200
+ def set_foreign_key(db_child, parent)
201
+ association_config.set_foreign_key(db_child, parent)
202
+ end
176
203
 
177
- def set_foreign_key(db_child, parent)
178
- @relational_association.set_foreign_key(db_child, parent)
179
- end
204
+ def set_parent_class_config(parent_config)
205
+ @parent_config = parent_config
206
+ end
180
207
 
181
- def associated?(db_parent, db_child)
182
- return false if child_config.db_class != db_child.class
183
- db_child.send(fk) == db_parent.id
208
+ def foreign_key_info
209
+ association_config.foreign_key_info(@parent_config)
210
+ end
184
211
  end
185
212
 
186
- def child_config
187
- @relational_association.local_config
188
- end
213
+ module LocalEndConfig
214
+ def child_config(db_parent)
215
+ association_config.remote_class_config(db_parent)
216
+ end
189
217
 
190
- def foreign_key_info
191
- @relational_association.foreign_key_info(@parent_config)
192
- end
193
- end
194
- # @private
195
- class BelongsToConfig
196
- include HashInitialization
197
- attr_reader :name, :owned, :fk, :fk_type, :child_classes
218
+ def set_foreign_key(db_parent, child)
219
+ association_config.set_foreign_key(db_parent, child)
220
+ end
198
221
 
199
- def init_relational_association(child_configs, parent_config)
200
- @relational_association = RelationalAssociation.new(fk: fk, fk_type: fk_type, local_config: parent_config, remote_configs: child_configs)
222
+ def fk_value(db_parent)
223
+ db_parent.send(fk)
201
224
  end
225
+ end
202
226
 
227
+ module ToOneConfig
203
228
  def get_child(parent)
204
229
  parent.send(name)
205
230
  end
206
231
 
207
- def set_child(parent, child)
232
+ def associate(parent, child)
208
233
  parent.send("#{name}=", child)
209
234
  end
235
+ end
210
236
 
211
- def set_foreign_key(db_parent, child)
212
- @relational_association.set_foreign_key(db_parent, child)
213
- end
214
-
215
- def associated?(db_parent, db_child)
216
- return false if child_config(db_parent).db_class != db_child.class
217
- fk_value(db_parent) == db_child.id
237
+ module ToManyConfig
238
+ def get_children(parent)
239
+ parent.send(name)
218
240
  end
219
241
 
220
- def child_config(db_parent)
221
- if @relational_association.polymorphic?
222
- @relational_association.remote_config_for_local_db_object(db_parent)
223
- else
224
- @relational_association.remote_configs.first
242
+ def associate(parent, child)
243
+ if get_children(parent).nil?
244
+ parent.send("#{name}=", [])
225
245
  end
246
+ get_children(parent) << child
226
247
  end
227
-
228
- def fk_value(db_parent)
229
- db_parent.send(fk)
230
- end
231
- end
232
-
233
- # @private
234
- class HasOneConfig
235
- include HashInitialization
236
- attr_reader :name, :owned, :fk, :fk_type, :child_class
237
-
238
- def init_relational_association(child_config, parent_config)
239
- @parent_config = parent_config
240
- @relational_association = RelationalAssociation.new(fk: fk, fk_type: fk_type, local_config: child_config, remote_configs: [parent_config])
241
248
  end
242
249
 
243
- def get_child(parent)
244
- parent.send(name)
245
- end
250
+ # @private
251
+ class HasManyConfig
252
+ include HashInitialization
253
+ include RemoteEndConfig
254
+ include ToManyConfig
246
255
 
247
- def set_child(parent, child)
248
- parent.send("#{name}=", child)
256
+ attr_reader :name, :owned, :fk, :fk_type, :child_class
257
+ attr_accessor :association_config
249
258
  end
250
259
 
251
- def set_foreign_key(db_child, parent)
252
- @relational_association.set_foreign_key(db_child, parent)
253
- end
260
+ # @private
261
+ class BelongsToConfig
262
+ include HashInitialization
263
+ include LocalEndConfig
264
+ include ToOneConfig
254
265
 
255
- def associated?(db_parent, db_child)
256
- return false if child_config.db_class != db_child.class
257
- db_child.send(fk) == db_parent.id
266
+ attr_reader :name, :owned, :fk, :fk_type, :child_classes
267
+ attr_accessor :association_config
258
268
  end
259
269
 
260
- def child_config
261
- @relational_association.local_config
262
- end
270
+ # @private
271
+ class HasOneConfig
272
+ include HashInitialization
273
+ include RemoteEndConfig
274
+ include ToOneConfig
263
275
 
264
- def foreign_key_info
265
- @relational_association.foreign_key_info(@parent_config)
276
+ attr_reader :name, :owned, :fk, :fk_type, :child_class
277
+ attr_accessor :association_config
266
278
  end
267
279
  end
268
-
269
- end