associate method

Future<OrmMigrationRecord> associate(
  1. String relationName,
  2. Model<Model> parent
)
inherited

Associates a belongsTo parent model and updates the foreign key.

This is a convenient helper that:

  1. Updates the foreign key field to match the parent's primary key
  2. Caches the parent model in the relation cache
  3. Marks the relation as loaded

Example:

final post = Post(id: 1, title: 'Hello');
final author = Author(id: 5, name: 'Alice');
await post.associate('author', author);
// post.authorId is now 5
// post.author is now the Alice instance

Implementation

Future<TModel> associate(String relationName, Model parent) async {
  final def = expectDefinition();
  final relationDef = def.relations.cast<RelationDefinition?>().firstWhere(
    (r) => r?.name == relationName,
    orElse: () => null,
  );

  if (relationDef == null) {
    throw ArgumentError(
      'Relation "$relationName" not found on ${def.modelName}',
    );
  }

  if (relationDef.kind != RelationKind.belongsTo) {
    throw ArgumentError(
      'associate() can only be used with belongsTo relations. '
      'Relation "$relationName" is ${relationDef.kind}',
    );
  }

  // Get the parent's primary key value
  final resolver = _resolveResolverFor(def);
  final context = _requireQueryContext(resolver);
  final parentDef = context.registry.expectByName(relationDef.targetModel);
  final parentPk = parentDef.primaryKeyField;
  if (parentPk == null) {
    throw StateError(
      'Parent model ${parentDef.modelName} must have a primary key',
    );
  }

  final parentPkValue = parentDef.toMap(
    parent as dynamic,
    registry: context.codecRegistry,
  )[parentPk.columnName];

  if (parentPkValue == null) {
    throw StateError(
      'Parent model ${parentDef.modelName} primary key value is null',
    );
  }

  // Find the foreign key field in this model
  final foreignKeyName = relationDef.foreignKey;
  final field = def.fields.firstWhere(
    (f) => f.columnName == foreignKeyName || f.name == foreignKeyName,
  );

  // Update the foreign key attribute
  _asAttributes.setAttribute(field.columnName, parentPkValue);

  // Cache the parent in relations
  _asRelations.setRelation(relationName, parent);

  return _self();
}