Home > Enterprise >  Room one-to-many, to many
Room one-to-many, to many

Time:01-09

I am little a bit confused on how i should set up a data class consisting of two lists. I have a data class looking like this

@Entity(tableName = "recipe")
data class Recipe(
@PrimaryKey(autoGenerate = false)
val recipeName: String,
//val keyIngrediens: List<KeyIngredient>,
//val steps: List<steps>

So for KeyIngrediens i have set it up like this and it works perfectly without problems

@Entity
data class KeyIngredients(
@PrimaryKey(autoGenerate = false)
val title: String,
val image: String,
val undertitle: Int,
val recipeName: String
)

data class RecipeWithkeyIngredients(
@Embedded val recipe: Recipe,
@Relation(
    parentColumn = "recipeName",
    entityColumn = "recipeName"
)
val keyIngredients: List<KeyIngredients>
)

So basically, i got it to work with one list and one object, but Im a bit confused as how i should handle it when i have two lists in a single object. Right now im calling RecipeWithKeyIngredients which returns the recipe object with the list of key ingredients, but i don't know how to make it also contain the steps list. In short it should be like RecipeWithkeyIngredientsANDsteps if that is possible.

CodePudding user response:

Assuming your Steps data class as follows:

@Entity
data class Steps(
    @PrimaryKay
    val stepName: String,
    val duration: Int,
    val recipeName: String,
    val rank: Int
)
data class RecipeWithKeyIngredientsAndSteps(
    @Embedded recipe: Recipe,
    @Relation(
        parentColumn = "recipeName",
        entityColumn = "recipeName"
    )
    val keyIngredients: List<KeyIngredients>,
    @Relation(
        parentColumn = "recipeName",
        entityColumn = "recipeName"
    )
    val steps: List<Steps>
)

At the end it's still a One-to-N Relationship

CodePudding user response:

This is not enough for recipes. A recipe contains many ingredients, an ingredient belongs to many recipes. So it should be handled with many-to-many relationship.

@Entity
data class Recipe(
  @PrimaryKey
  val id: Long,
  val name: String,
  val steps: List<String>
)

@Entity
data class KeyIngredient(
  @PrimaryKey
  val id: Long,
  val title: String,
  val image: String,
  val undertitle: Int,
)

@Entity(
  primaryKeys = ["recipeId", "keyIngredientId"]
)
data class RecipeKeyIngredient(     
  val recipeId: Long,
  val keyIngredientId: Long
)

Get the list of ingredients

data class IngredientsOfRecipe (
    @Embedded
    val recipe: Recipe,
    @Relation(
            parentColumn = "recipeId",
            entity = KeyIngredient::class,
            entityColumn = "ingredientId",
            associateBy = Junction(
                    value = RecipeKeyIngredient::class,
                    parentColumn = "recipeId",
                    entityColumn = "keyIngredientId"
            )
    )
    val keyIngredients: List<KeyIngredient>
)

Get the list of recipes

data class RecipesWithIngredient(
  @Embedded
  val ingredient: Ingredient,
  @Relation(
        parentColumn = "ingredientId",
        entity = Recipe::class,
        entityColumn = "recipeId",
        associateBy = Junction(
                value = RecipeIngredient::class,
                parentColumn = "ingredientId",
                entityColumn = "recipeId"
        )
  )
  val recipes: List<Recipe>
)

Now you can query database for the result as:

@Dao
interface RecipeKeyIngredientDao {
  @Query("SELECT * FROM Recipe")
  fun getIngredientsOfRecipe(): LiveData<List<IngredientWithRecipes>>

  @Query("SELECT * FROM KeyIngredient")
  fun getRecipesWithIngredient(): LiveData<List<RecipeWithIngredients>>
}

For the other part of the question, a recipe typically contains specific set of steps (instructions?) which belongs to the Recipe table.

  •  Tags:  
  • Related