detach method
- Model sibling, {
- required ModelRelationshipType relationship,
- PivotTable<
Model, Model> ? table, - DatabaseDisk disk = Model.defaultDisk,
Detaches sibling from this model using the given relationship type.
Behavior depends on the relationship:
hasOne/hasMany: clears this model's foreign key fromsiblingbelongsToOne: clears the sibling foreign key from this modelbelongsToMany: removes the pivot-table record
For belongsToMany, table is required.
Returns true when the relationship is successfully detached; otherwise
returns false.
Example:
await user.detach(
profile,
relationship: ModelRelationshipType.hasOne,
);
await user.detach(
role,
relationship: ModelRelationshipType.belongsToMany,
table: userRolesPivot,
disk: DatabaseDisk.sqlite,
);
Implementation
Future<bool> detach(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: null});
case .file:
case .s3:
final childField = "${childPrefix}_uuid";
return await sibling.update(withJson: {childField: null});
}
case .belongsToOne:
switch (disk) {
case .sqlite:
case .pgsql:
final siblingField = "${siblingPrefix}_id";
return update(withJson: {siblingField: null});
case .file:
case .s3:
final siblingField = "${siblingPrefix}_uuid";
return await update(withJson: {siblingField: null});
}
case .belongsToMany:
if(table == null) {
return false;
}
switch(disk) {
case .sqlite:
final sqliteDB = App().container.make<SQLiteDatabase>();
final childPrefix = getInstanceTableSingularName();
final childField = "${childPrefix}_id";
final siblingPrefix = sibling.getInstanceTableSingularName();
final siblingField = "${siblingPrefix}_id";
await sqliteDB.delete(
table.name,
where: '$childField = ? AND $siblingField = ?',
whereArgs: [id, sibling.id],
);
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 detaching sibling", {
"origin": "ext ModelRelationshipOps detach()",
"error": e.toString(),
"stack": stack.toString()
});
return false;
}
}