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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/api_blocks/blueprinter/association_extractor.rb', line 15
def (association_name, object, local_options, options = {})
return (association_name, object, local_options, options) unless options.fetch(:batch, true)
association = object.association(association_name)
if association.is_a?(ActiveRecord::Associations::HasManyThroughAssociation)
return (association_name, object, local_options, options)
end
raise 'Cannot load blueprints with a `proc` blueprint option with batch-loader' if options[:blueprint].is_a?(Proc)
join_key = ::ApiBlocks::Blueprinter::JoinKeys.join_keys(
association.reflection
)
association_id = object.send(join_key.foreign_key)
association_klass = association.reflection.class_name
default_value = case association
when ActiveRecord::Associations::HasManyAssociation
[]
end
view = options[:view] || :default
scope = if options[:block].present?
options[:block].call(object, local_options)
else
{}
end
BatchLoader.for(association_id).batch(
default_value: default_value,
key: [association_name, association_klass, view, options[:blueprint], scope]
) do |ids, loader, args|
model = association_klass.safe_constantize
scope = args[:key].last
case association
when ActiveRecord::Associations::HasManyAssociation
model.where(join_key.key => ids).merge(scope).each do |record|
loader.call(record.send(join_key.key)) do |memo|
memo << render_blueprint(record, local_options, options)
memo.uniq
end
end
when ActiveRecord::Associations::HasOneAssociation
model.where(join_key.key => ids).merge(scope).each do |record|
loader.call(
record.send(join_key.key),
render_blueprint(record, local_options, options)
)
end
when ActiveRecord::Associations::BelongsToAssociation
model.where(join_key.key => ids).merge(scope).each do |record|
loader.call(
record.id,
render_blueprint(record, local_options, options)
)
end
else
raise "unsupported association kind #{association.class.name}"
end
end
end
|