Retrieve room id from the project when following/unfollowing

Max Brunsfeld created

Previously, we were accidentally using the project id as the room id.

Change summary

crates/collab/src/db.rs  | 24 +++++++++++++++++++++---
crates/collab/src/rpc.rs |  6 ++----
2 files changed, 23 insertions(+), 7 deletions(-)

Detailed changes

crates/collab/src/db.rs 🔗

@@ -1720,12 +1720,12 @@ impl Database {
 
     pub async fn follow(
         &self,
-        room_id: RoomId,
         project_id: ProjectId,
         leader_connection: ConnectionId,
         follower_connection: ConnectionId,
     ) -> Result<RoomGuard<proto::Room>> {
         self.room_transaction(|tx| async move {
+            let room_id = self.room_id_for_project(project_id, &*tx).await?;
             follower::ActiveModel {
                 room_id: ActiveValue::set(room_id),
                 project_id: ActiveValue::set(project_id),
@@ -1749,16 +1749,15 @@ impl Database {
 
     pub async fn unfollow(
         &self,
-        room_id: RoomId,
         project_id: ProjectId,
         leader_connection: ConnectionId,
         follower_connection: ConnectionId,
     ) -> Result<RoomGuard<proto::Room>> {
         self.room_transaction(|tx| async move {
+            let room_id = self.room_id_for_project(project_id, &*tx).await?;
             follower::Entity::delete_many()
                 .filter(
                     Condition::all()
-                        .add(follower::Column::RoomId.eq(room_id))
                         .add(follower::Column::ProjectId.eq(project_id))
                         .add(
                             Condition::any()
@@ -1788,6 +1787,25 @@ impl Database {
         .await
     }
 
+    async fn room_id_for_project(
+        &self,
+        project_id: ProjectId,
+        tx: &DatabaseTransaction,
+    ) -> Result<RoomId> {
+        #[derive(Copy, Clone, Debug, EnumIter, DeriveColumn)]
+        enum QueryAs {
+            RoomId,
+        }
+
+        Ok(project::Entity::find_by_id(project_id)
+            .select_only()
+            .column(project::Column::RoomId)
+            .into_values::<_, QueryAs>()
+            .one(&*tx)
+            .await?
+            .ok_or_else(|| anyhow!("no such project"))?)
+    }
+
     pub async fn update_room_participant_location(
         &self,
         room_id: RoomId,

crates/collab/src/rpc.rs 🔗

@@ -1719,7 +1719,6 @@ async fn follow(
     response: Response<proto::Follow>,
     session: Session,
 ) -> Result<()> {
-    let room_id = RoomId::from_proto(request.project_id);
     let project_id = ProjectId::from_proto(request.project_id);
     let leader_id = request
         .leader_id
@@ -1751,7 +1750,7 @@ async fn follow(
     let room = session
         .db()
         .await
-        .follow(room_id, project_id, leader_id, follower_id)
+        .follow(project_id, leader_id, follower_id)
         .await?;
     room_updated(&room, &session.peer);
 
@@ -1759,7 +1758,6 @@ async fn follow(
 }
 
 async fn unfollow(request: proto::Unfollow, session: Session) -> Result<()> {
-    let room_id = RoomId::from_proto(request.project_id);
     let project_id = ProjectId::from_proto(request.project_id);
     let leader_id = request
         .leader_id
@@ -1784,7 +1782,7 @@ async fn unfollow(request: proto::Unfollow, session: Session) -> Result<()> {
     let room = session
         .db()
         .await
-        .unfollow(room_id, project_id, leader_id, follower_id)
+        .unfollow(project_id, leader_id, follower_id)
         .await?;
     room_updated(&room, &session.peer);