I have 2 entities User
and Location
with a Many-to-Many link. The creation of a relationship seems to work but not the deletion.
The goal is not to delete the entities but only the relationships.
Should the deletion be done on both entities?
Only the one with the @Backlink?
I have tried several solutions based on .remove()
+ put()
but without success.
@Entity()
class LocationModel {
@Id()
int localId = 0;
@Unique(onConflict: ConflictStrategy.replace)
int id;
@Backlink('location')
final items = ToMany<ItemModel>();
final users = ToMany<UserModel>();
}
@Entity()
class UserModel {
@Id()
int localId = 0;
@Unique(onConflict: ConflictStrategy.replace)
String guid;
@Backlink('user')
final items = ToMany<ItemModel>();
@Backlink()
final locations = ToMany<LocationModel>();
}
A method comes to update the relationships between the location and the users. Users is the list of users of the location (given by an API). The goal is to update the relationships (and only the relationships).
The idea will also be to do something similar with a method in the user collection to have a User and a list of Location to come update.
LocationModel updateUsers(
LocationModel locationModel,
List<UserModel> users,
) {
// Update users that may still have a link to this location
final usersByLocation = userCollection.getByLocation(locationModel.localId);
// Remove relationship with location if no users (users.isEmpty) or no longer present in users list
final userToRemoveLocation = users.isEmpty
? usersByLocation
: usersByLocation
.where((user) => !users.any((u) => u.guid == user.guid))
.toList();
for (var user in userToRemoveLocation) {
user.locations.remove(locationModel);
userCollection.put(user);
final locationInDb = locationBox.get(locationModel.localId);
if (locationInDb != null) {
locationInDb.users.remove(user);
locationBox.put(locationInDb);
}
}
// Creation of new relationships between location and users (users list)
for (var user in users) {
final userInDb = userCollection.getByServerId(user.guid);
if (userInDb != null) {
userInDb.locations.add(locationModel);
userCollection.put(userInDb);
final locationInDb = locationBox.get(locationModel.localId);
if (locationInDb != null) {
locationInDb.users.add(user);
locationBox.put(locationInDb);
}
}
}
return locationModel;
}
Adding a @Backlink
annotation to a ToMany
property just accesses the relation pointed to by @Backlink
in the “reverse” direction. It does not actually create another relation.
So to update the relation, it only needs to be done “from either side”. E.g. this should be enough:
for (var user in userToRemoveLocation) {
user.locations.remove(locationModel);
userCollection.put(user);
// final locationInDb = locationBox.get(locationModel.localId);
// if (locationInDb != null) {
// locationInDb.users.remove(user);
// locationBox.put(locationInDb);
// }
}
https://docs.objectbox.io/relations#access-many-to-many-in-the-reverse-direction
1