2

I'm making an Workout log app.

One Workout has multiple sets.

I want to store this in a one-to-many relationship in Room.

In conclusion, I succeeded in saving, but I'm not sure what one class does.

All of the other example sample code uses this class, so I made one myself, but it doesn't tell me what it means.

WorkoutWithSets

data class WorkoutWithSets(
    @Embedded val workout: Workout,
    @Relation (
        parentColumn = "workoutId",
        entityColumn = "parentWorkoutId"
    )
    val sets: List<WorkoutSetInfo>
)

The following two entity classes seem to be sufficient to express a one-to-many relationship. (Stored in Room)

Workout

@Entity
data class Workout(
    @PrimaryKey(autoGenerate = true)
    var workoutId: Long = 0,
    var title: String = "",
    var memo: String = "",
)

It seems that the following two entity classes are sufficient enough to store a one-to-many relationship.. (stored in Room)

WorkoutSetInfo

@Entity(
    foreignKeys = [
        ForeignKey(
            entity = Workout::class,
            parentColumns = arrayOf("workoutId"),
            childColumns = arrayOf("parentWorkoutId"),
            onDelete = ForeignKey.CASCADE
        )
    ]
)
data class WorkoutSetInfo(
    @PrimaryKey(autoGenerate = true)
    val id: Long = 0,
    val set: Int,
    var weight: String = "",
    var reps: String = "",
    var unit: WorkoutUnit = WorkoutUnit.kg,
    val parentWorkoutId: Long = 0
)

Even if the WorkoutWithSet class does not exist, the Workout and WorkoutSetInfo classes are stored in Room.

What does WorkoutWithSets class mean? (or where should I use it?)

ybybyb
  • 1,385
  • 1
  • 12
  • 33

1 Answers1

1

What does WorkoutWithSets class mean?

It is a class that can be used to retrieve a Workout along with all the related WorkoutSetInfos via a simple @Query that just retrieves the parent Workouts.

What Room does is add an additional query that retrieves the children (WorkoutSetInfo's) for each Workout.

The result being a list of WorkOutWithSets each element (a Workout) containing/including a list of all the related WorkoutSetInfo's.

You would use this when you want to process a Workout (or many Workouts) along with the related WorkoutSetInfo's (aka the child WorkoutSetInfo's for the parent Workout).

What Room does is consider the type (objects) to be returned.

So if you had

@Query("SELECT * FROM workout")
fun getJustWorkouts(): List<Workout>

then the function would return just a list of Workout objects.

But if you had

@Query("SELECT * FROM workout")
fun getWorkoutsWithSets(): List<WorkoutWithSets>

then the function would return a list of WorkoutWithSets and thus the parent Workouts with the child WorkoutSetInfo's.

What Room does is build and execute an underlying query, for eack Workout extracted, along the lines of "SELECT * FROM workoutInfoSet WHERE workout.workoutId = parentWorkoutId" and hence why it suggests the use of the @Transaction annotation (the build will include a warning if @Transaction is not coded).

MikeT
  • 51,415
  • 16
  • 49
  • 68
  • Thanks, but does `Parent Workout` mean `Workout` class? – ybybyb Jul 21 '22 at 21:28
  • 1
    @ybybyb **yes**, the specific (One) Workout that is the parent to the (Many (which may in fact be none)) WorkoutSetInfo's. – MikeT Jul 22 '22 at 00:32