10
11
12
13
14
15
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
|
# File 'lib/mongoid-denormalize.rb', line 10
def denormalize(*args)
options = args.pop
unless options.is_a?(Hash) && (from = options[:from]&.to_s)
raise ArgumentError, 'Option :from is needed (e.g. delegate :name, from: :user).'
end
args.each { |field| field "#{from}_#{field}" }
before_save do
if send(from) && send("#{from}_id_changed?")
args.each do |field|
send("#{from}_#{field}=", send(from).send(field))
end
end
end
from_class = (relations[from].class_name || relations[from].name.capitalize).constantize
child_model_name = model_name
child_inverse_of = relations[from].inverse_of
from_class.send(:after_update) do
attributes = {}
args.each { |field| attributes["#{from}_#{field}"] = send(field) }
relation = relations[child_inverse_of.to_s] ||
relations[child_model_name.plural] ||
relations[child_model_name.singular]
unless relation
raise "Option :inverse_of is needed for 'belongs_to :#{from}' into #{child_model_name.name}."
end
case relation.relation.to_s
when 'Mongoid::Relations::Referenced::One'
document = send(relation.name)
document.collection.update_one({_id: document._id}, {'$set' => attributes}) if document
when 'Mongoid::Relations::Referenced::Many'
send(relation.name).update_all('$set' => attributes)
else
raise "Relation type unsupported: #{relation.relation}"
end
end
end
|