associate method
Associates a belongsTo parent model and updates the foreign key.
This is a convenient helper that:
- Updates the foreign key field to match the parent's primary key
- Caches the parent model in the relation cache
- 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();
}