attach method
- Model sibling, {
- required ModelRelationshipType relationship,
- PivotTable<
Model, Model> ? table, - DatabaseDisk disk = Model.defaultDisk,
Attaches sibling to this model using the given relationship type.
Behavior depends on the relationship:
hasOne/hasMany: writes this model's foreign key ontosiblingbelongsToOne: writes the sibling foreign key onto this modelbelongsToMany: inserts a pivot-table record
For belongsToMany, table is required.
Returns true when the relationship is successfully attached; otherwise
returns false.
Example:
await user.attach(
profile,
relationship: ModelRelationshipType.hasOne,
);
await user.attach(
role,
relationship: ModelRelationshipType.belongsToMany,
table: UserRolePivotTable,
disk: DatabaseDisk.sqlite,
);
Implementation
Future<bool> attach(Model sibling, {required ModelRelationshipType relationship, PivotTable? table, DatabaseDisk disk = Model.defaultDisk,}) async {
try {
final childPrefix = getInstanceTableSingularName();
final siblingPrefix = sibling.getInstanceTableSingularName();
switch (relationship) {
case .hasOne:
case .hasMany:
switch (disk) {
case .sqlite:
case .pgsql:
final childField = "${childPrefix}_id";
return await sibling.update(withJson: {childField: id});
case .file:
case .s3:
final childField = "${childPrefix}_uuid";
return await sibling.update(withJson: {childField: uuid});
}
case .belongsToOne:
switch (disk) {
case .sqlite:
case .pgsql:
final siblingField = "${siblingPrefix}_id";
return update(withJson: {siblingField: sibling.id});
case .file:
case .s3:
final siblingField = "${siblingPrefix}_uuid";
return await update(withJson: {siblingField: sibling.uuid});
}
case .belongsToMany:
if(table == null) {
return false;
}
switch(disk) {
case .sqlite:
final sqliteDB = App().container.make<SQLiteDatabase>();
final tableName = table.name;
final childPrefix = getInstanceTableSingularName();
final childField = "${childPrefix}_id";
final siblingPrefix = sibling.getInstanceTableSingularName();
final siblingField = "${siblingPrefix}_id";
final createdAt = DateTime.now().toIso8601String();
final updatedAt = DateTime.now().toIso8601String();
await sqliteDB.rawInsert(
'INSERT INTO $tableName ($childField, $siblingField, created_at, updated_at) VALUES(?, ?, ?, ?)',
[id, sibling.id, createdAt, updatedAt]
);
return true;
// todo : pivot tables currently implemented for sqlite.
case DatabaseDisk.file:
throw UnimplementedError();
case DatabaseDisk.pgsql:
throw UnimplementedError();
case DatabaseDisk.s3:
throw UnimplementedError();
}
}
} catch(e,stack) {
App().archeryLogger.error("Error attaching sibling", {"origin": "ext ModelRelationshipOps attach", "error": e.toString(), "stack": stack.toString()});
return false;
}
}