16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/yapper/document/relation.rb', line 16
def has_many(relation, options={})
self.relations[:has_many] << { relation => options } unless self.relations[:has_many].find { |r,o| r == relation }
define_method(relation) do
Object.qualified_const_get(relation.to_s.singularize.camelize).where("#{self._type.underscore}_id".to_sym => self.id)
end
define_method("#{relation}=") do |docs|
raise "You must pass an array of objects or attributes" unless docs.is_a?(Array)
raise "All elements in the array must be of the same type" unless docs.all? { |doc| doc.is_a?(docs.first.class) }
changes = {}
db.execute do |txn|
docs.each do |doc|
if doc.is_a?(Yapper::Document)
if doc.persisted?
doc.assign_attributes("#{self._type.underscore}" => self)
if options[:embedded]
changes["#{relation.singularize}_ids"] ||= []
changes["#{relation.singularize}_ids"] << doc.id
end
@queued_saves << [doc, options]
else
doc.assign_attributes("#{self._type.underscore}" => self)
if options[:embedded]
changes[relation] ||= []
changes[relation] << doc.attributes
end
@queued_saves << [doc, options]
end
elsif doc.is_a?(Hash)
doc = doc.with_indifferent_access
klass = Object.qualified_const_get(relation.singularize.to_s.camelize)
instance = klass.find(doc[:id]) if doc[:id]
instance ||= klass.new
instance.assign_attributes("#{self._type.underscore}" => self)
instance.assign_attributes(doc)
if options[:embedded]
changes[relation] ||= []
changes[relation] << instance.attributes
end
@queued_saves << [instance, options]
else
raise "Must pass either attributes or an object"
end
end
end
@changes.merge!(changes)
end
end
|