attachPivot method

Future<void> attachPivot(
  1. String relName,
  2. RelationalModel<RelationalModel> related, {
  3. Map<String, dynamic>? pivot,
})

Attach with pivot table. Saved into db

Implementation

Future<void> attachPivot(
  String relName,
  RelationalModel related, {
  Map<String, dynamic>? pivot,
}) async {
  final rel = relations()[relName];

  if (rel == null) {
    throw Exception(
      "Relation '$relName' is not defined on ${runtimeType}."
    );
  }

  if (rel.type != RelationType.belongsToMany) {
    throw Exception(
      "attachPivot() can only be used with belongsToMany relations. "
      "'$relName' is ${rel.type}."
    );
  }

  final parentId = toMap()[primaryKey];
  final relatedId = related.toMap()[related.primaryKey];

  if (parentId == null) {
    throw Exception(
      "Cannot attachPivot('$relName'): parent model is not saved."
    );
  }

  if (relatedId == null) {
    throw Exception(
      "Cannot attachPivot('$relName'): related model is not saved."
    );
  }

  await dbService.insert(rel.pivotTable!, {
      rel.pivotForeignKey!: parentId,
      rel.pivotRelatedKey!: relatedId,
      ...?pivot,
    },
    // conflictAlgorithm: ConflictAlgorithm.ignore
  );

  // Optional: keep in-memory relation consistent if already loaded
  final current = getRelation(relName);

  if (current is List) {
    final relatedPk = related.primaryKey;
    final relatedIdValue = related.toMap()[relatedPk];

    final exists = current.any(
      (e) =>
        (e as dynamic).toMap()[relatedPk] == relatedIdValue,
    );

    if (!exists) {
      // Attach pivot data to the related model
      (related as dynamic).pivot = {
        rel.pivotForeignKey!: parentId,
        rel.pivotRelatedKey!: relatedId,
        ...?pivot,
      };

      current.add(related);
    }
  }
}