lib/terrestrial/graph_loader.rb in terrestrial-0.1.1 vs lib/terrestrial/graph_loader.rb in terrestrial-0.3.0

- old
+ new

@@ -6,58 +6,81 @@ @object_load_pipeline = object_load_pipeline end attr_reader :datasets, :mappings, :object_load_pipeline - def call(mapping_name, record, eager_data = {}) + def call(mapping_name, record, eager_data_graph = {}) mapping = mappings.fetch(mapping_name) - load_record(mapping, record, eager_data) + load_record(mapping, record, eager_data_graph) end private - def load_record(mapping, record, eager_data) - associations = load_associations(mapping, record, eager_data) + def load_record(mapping, record, eager_data_graph) + associations = load_associations(mapping, record, eager_data_graph) object_load_pipeline.call(mapping, record, Hash[associations]) end - def load_associations(mapping, record, eager_data) + def load_associations(mapping, record, eager_data_graph) mapping.associations.map { |name, association| - assoc_eager_data = eager_data.fetch(name, {}) + load_association(name, association, record, eager_data_graph) + } + end - data_superset = assoc_eager_data.fetch(:superset) { - load_from_datasets(association) - } + def load_association(name, association, record, eager_data_graph) + association_superset, deeper_eager_data = eager_or_lazy_data( + name, + association, + eager_data_graph, + ) - [ - name, - association.build_proxy( - record: record, - data_superset: data_superset, - loader: ->(associated_record, join_records = []) { - join_records.map { |jr| - join_mapping = mappings.fetch(association.join_mapping_name) - object_load_pipeline.call(join_mapping, jr) - } + [ + name, + association.build_proxy( + record: record, + data_superset: association_superset, + loader: recursive_loader(association, deeper_eager_data), + ) + ] + end - call( - association.mapping_name, - associated_record, - assoc_eager_data.fetch(:associations, {}) - ) - }, - ) - ] - } + def eager_or_lazy_data(name, association, eager_data_graph) + eager_data = eager_data_graph.fetch(name, {}) + + association_superset = eager_data.fetch(:superset) { default_dataset(association) } + deeper_eager_data = eager_data.fetch(:associations, {}) + + [association_superset, deeper_eager_data] end - def load_from_datasets(association) + def default_dataset(association) association - .mapping_names - .map { |name| mappings.fetch(name) } - .map(&:namespace) - .map { |ns| datasets[ns] } + .mapping_names + .map { |name| mappings.fetch(name) } + .map(&:namespace) + .map { |ns| datasets[ns] } + end + + def recursive_loader(association, eager_data_graph) + ->(associated_record, join_records = []) { + load_and_ignore_join_records(association, join_records) + + call( + association.mapping_name, + associated_record, + eager_data_graph, + ) + } + end + + def load_and_ignore_join_records(association, join_records) + join_records.each do |jr| + mapping = mappings.fetch(association.join_mapping_name) + object_load_pipeline.call(mapping, jr) + end + + nil end end end