class SequelMapper::ManyToManyAssociation

Attributes

association_foreign_key[R]
association_key[R]
foreign_key[R]
join_dataset[R]
join_mapping_name[R]
key[R]
mapping_name[R]
order[R]
proxy_factory[R]

Public Class Methods

new(mapping_name:, foreign_key:, key:, proxy_factory:, association_foreign_key:, association_key:, join_mapping_name:, join_dataset:, order:) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 5
def initialize(mapping_name:, foreign_key:, key:, proxy_factory:, association_foreign_key:, association_key:, join_mapping_name:, join_dataset:, order:)
  @mapping_name = mapping_name
  @foreign_key = foreign_key
  @key = key
  @proxy_factory = proxy_factory
  @association_foreign_key = association_foreign_key
  @association_key = association_key
  @join_mapping_name = join_mapping_name
  @join_dataset = join_dataset
  @order = order
end

Public Instance Methods

build_proxy(data_superset:, loader:, record:) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 22
def build_proxy(data_superset:, loader:, record:)
 proxy_factory.call(
    query: build_query(data_superset, record),
    loader: ->(record_list) {
      record = record_list.first
      join_records = record_list.last

      loader.call(record, join_records)
    },
    mapping_name: mapping_name,
  )
end
build_query(superset, parent_record) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 50
def build_query(superset, parent_record)
  order
    .apply(
      superset.join(join_mapping_name, association_foreign_key => key)
        .where(foreign_key => foreign_key_value(parent_record))
    )
    .lazy.map { |record|
      [record, [foreign_keys(parent_record, record)]]
    }
end
delete(parent_record, collection, &block) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 141
def delete(parent_record, collection, &block)
  flat_list_of_just_join_records(parent_record, collection, &block)
end
dump(parent_record, collection, &block) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 137
def dump(parent_record, collection, &block)
  flat_list_of_records_and_join_records(parent_record, collection, &block)
end
eager_superset(superset, associated_dataset) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 35
def eager_superset(superset, associated_dataset)
  # TODO: All these keys can be confusing, write some focused tests.
  eager_join_dataset = Dataset.new(
    join_dataset
      .where(foreign_key => associated_dataset.select(association_key))
      .to_a
  )

  eager_dataset = superset
    .where(key => eager_join_dataset.select(association_foreign_key))
    .to_a

  JoinedDataset.new(eager_dataset, eager_join_dataset)
end

Private Instance Methods

flat_list_of_just_join_records(parent_record, collection, &block) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 151
def flat_list_of_just_join_records(parent_record, collection, &block)
  record_join_record_pairs(parent_record, collection, &block)
    .map { |(_records, join_records)| join_records }
    .flatten(1)
end
flat_list_of_records_and_join_records(parent_record, collection, &block) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 147
def flat_list_of_records_and_join_records(parent_record, collection, &block)
  record_join_record_pairs(parent_record, collection, &block).flatten(1)
end
foreign_key_value(record) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 177
def foreign_key_value(record)
  record.fetch(key)
end
foreign_keys(parent_record, record) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 170
def foreign_keys(parent_record, record)
  {
    foreign_key => foreign_key_value(parent_record),
    association_foreign_key => record.fetch(association_key),
  }
end
record_join_record_pairs(parent_record, collection, &block) click to toggle source
# File lib/sequel_mapper/many_to_many_association.rb, line 157
def record_join_record_pairs(parent_record, collection, &block)
  (collection || []).map { |associated_object|
    records = block.call(mapping_name, associated_object, _no_foreign_key = {})

    join_records = records.take(1).flat_map { |record|
      fks = foreign_keys(parent_record, record)
      block.call(join_mapping_name, fks, fks)
    }

    records + join_records
  }
end