1

I am working on a system that allows users to track their musical practice. The system allows users to create 'exercises' that store a few pieces of information like name, description and external links. These exercises are created by the user and will belong to the user: the user ID is a property of the exercise (one-to-many). When a user searches for exercises, the system only shows him the exercises that have a matching user ID.

I have now introduced the concept of student and teacher users. I would like teachers to be able to share some of their exercises with their students as they see fit.

The way I have implemented this at the moment is:

  • create a class that represents a student/teacher membership (typical many-to-many)
  • subscribe a student to a teacher
  • edit the service that gets the exercises for a user to also include all exercises from any teacher the student is subscribed

This works fine, but it doesn't allow teachers to decide which exercises the student can see, as the student will see all the exercises from the teacher.

I was thinking of creating another 'membership' class that I can use to register a user to an exercise, which would achieve the goal. However, I don't like this idea as things would get a bit messy:

  • if memberships are used to get the relevant exercises, then it would make more sense to use memberships for exercises that the user itself created, instead of saving the user ID on the exercise itself

Essentially, I now need a many-to-many relationship between user and exercise and I cannot think of another way to achieve it other than what I mentioned before (remove the user ID from the exercise object and create a membership class to assign exercises to users, so that now exercises can have multiple users that can access them)

Here is a diagram showing the objects and how they relate to each other (ignore the other objects, I included them to give more context): model diagram

This is an example of a possible scenario with different students and teachers: enter image description here

Does the above sound like a sensible approach?

I'm afraid I might be missing some basic key social media concept that would make this problem easy to solve, as I think this is a very similar problem to 'how to share a post with only some other users' on a social media platform.

Kappacake
  • 119
  • 4
  • Please leave a comment if you are down-voting so I can improve the question – Kappacake Apr 01 '22 at 14:56
  • I'd let the teachers create lists of exercises. Like paid exercises and free exercises and then let the teachers add what students he wants to both. The relation (between students and exercises) would be through those lists. – Caique C. Apr 01 '22 at 15:49
  • @CaiqueC. The problem with that is that students can also create exercises for themselves. At the domain level, both student and teachers are currently 'User' objects - the concept of teacher/student doesn't exist at that level (the app doesn't currently have this student/teacher concept; I'm in the process of adding it and trying to integrate it in the current system) – Kappacake Apr 01 '22 at 16:40

1 Answers1

2

You have to distinguish between

  • the owner of an exercise, and

  • it's visibility (or accessibility) to other users

The first relationship is a 1:M relationship, hence your exercise will still need a user id (call it something like OwnerID), even when the second one is implemented as an M:N relationship.

Currently, you are trying to use a general term "membership" to mix up both, and that's why things become messy.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • That makes sense. The way I implemented this at the moment is to replace the ```Guid UserId``` with ```IEnumerable AssignedUsers```, which works fine in terms of sharing objects between users, but leaves me with the question of 'who can edit/delete an exercise?', which would be very easy to answer if I had an owner for the object. On the other hand, it wouldn't help with allowing a user other than the owner to edit – Kappacake Apr 05 '22 at 11:14
  • @demonicdaron: specific user rights (for example, the permission to edit even if a user is not the owner) can be stored in the junction table which implements the visibility (or accessibility) relationship. – Doc Brown Apr 05 '22 at 11:49
  • Right, I see. What is the point of the 'ownerId' at this point? At the moment, I removed the need for a junction table based on the fact that I only need to access the userIds from the object and not viceversa – Kappacake Apr 05 '22 at 13:05
  • 1
    @demonicdaron: well, it expresses ownership, which means, when the owner of an exercise gets deleted, their exercises get deleted as well. Or, the owner may be the only one who has permissions to change the accessibility for other users. But if you don't need that concept, because exercises don't belong to anyone special and can exist without any owner (which is quite contrary to the wording in your question), then you can probably omit the OwnerID. – Doc Brown Apr 05 '22 at 13:16