0

Play フレームワーク テンプレートに渡されたリストの反復処理に問題があります。基本的に、多対多の関連付けから取得するクエリがあり、親キーを 1 回レンダリングし、関連付けられたキーを数回レンダリングしたいと考えています。

以下は、私が使用している実際のコードです。

Slick、Scala、Play 2.0 を使用して、次のテーブル スキーマを作成しました。

object Recipes extends Table[(Long, String, String)]("RECIPES") {
  def id = column[Long]("REC_ID", O.PrimaryKey, O.AutoInc)
  def cuisine = column[String]("CUISINE")
  def instructions = column[String]("INSTRUCTIONS")
  def * = id ~ cuisine ~ instructions
}

object Ingredients extends Table[(Long, String, String)]("INGREDIENTS") {
  def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
  def brand = column[String]("BRAND")
  def name = column[String]("NAME")
  def * = id ~ brand ~ name
}

object RecipeIngredient extends Table[(Long, Long, Long, Int, String)]("REC_ING") {
  def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)

  def recID = column[Long]("REC_ID")
  def ingID = column[Long]("ING_ID")
  def quantity = column[Int]("QUANTITY")
  def units = column[String]("UNITS")
  def * = id ~ recID ~ ingID ~ quantity ~ units
  def recipe = foreignKey("REC_FK", recID, Recipes)(_.id)
  def ingredient = foreignKey("ING_FK", ingID, Ingredients)(_.id)
}

Slick を使用して、コントローラー内で次のクエリを生成q.listし、ビューに渡します。アイデアは、ID 1 とそれに関連するすべての成分を含むレシピを渡してレンダリングすることです。

val recID = 1.longValue() // Just a test to get the Recipe with ID === 1
val q = for {
    r <- Recipes if r.id === recID
    ri <- RecipeIngredient if ri.recID === recID
i <-Ingredients if i.id === ri.ingID
} yield (r.id, r.cuisine, r.instructions, ri.quantity, ri.units, i.brand, i.name)

私の見解は次のとおりです。

@(message: String, result: List[(Long, String, String, Int, String, String, String)])

@main("Site name") {

    @for((id, cuisine,instructions, quantity, units, brand, name) <- result) {

    <h2>--Recipe--</h2>
      RecID: @id <br>
      Cuisine: @cuisine <br>
      Instructions: @instructions <br>

      <h2>--Ingredients--</h2>
      Ingredient: @quantity @units of @brand @name<br>
  }


}

これはすべて問題ありませんが、次のような出力が得られます。

--Recipe--
RecID: 1 
Cuisine: Chinese 
Instructions: Instructions here..

--Ingredients--
Ingredient: 3 cloves of Generic Ginger

--Recipe--
RecID: 1 
Cuisine: Chinese 
Instructions: Instructions here..

--Ingredients--
Ingredient: 3 slices of Generic Cucumber

ご覧のとおり、レシピ自体は 2 回繰り返されます。私が最終的に望むのは、一度印刷されたレシピと、その後に関連する材料のリストが繰り返されて表示されることです (複数の材料がある場合があります)。

これを達成する方法についてのアイデアはありますか?

4

2 に答える 2

1

ベスト プラクティス/これを行うためのより洗練された方法に関しては、レシピのすべての情報を保持する Recipe ケース クラスの作成を検討する必要があります。これにより、コードが少しきれいになり、操作が簡単になります。

case class Recipe(val id: Long, val cuisine: String, val instructions: String, val quantity: Int, val units: String, val brand: String, val name: String)

注: ビュー内のフィールドにアクセスするときに使いやすいように、すべてのフィールドは明示的に vals とラベル付けされています。その後、クエリをオブジェクトに変換できます ( scala slick query return valueから)

def getRecipe(recID: Long): Option[Recipe] = {
  val q = for {
    r <- Recipes if r.id === recID
    ri <- RecipeIngredient if ri.recID === recID
    i <-Ingredients if i.id === ri.ingID
  } yield (r.id, r.cuisine, r.instructions, ri.quantity, ri.units, i.brand, i.name)
  q.firstOption map { case (id, cui, ins, qua, uni, bra, na) => Recipe(id, cui, ins, qua, uni, bra, na) }
}

次に、これをビューに渡すことができます。

@(message: String, recipe: Recipe)

@main("Site name") {

@recipe match {
  case r:Some(Recipe) => {
    <h2>--Recipe--</h2>
    RecID: @r.id <br>
    Cuisine: @r.cuisine <br>
    Instructions: @r.instructions <br>

    <h2>--Ingredients--</h2>
    Ingredient: @r.quantity @r.units of @r.brand @r.name<br>
  }
  case None => {
    <h2>No Recipe</h2>
  }
}
}

Recipe ケース クラスのコンパニオン オブジェクト クラスを作成する、ビューに渡される Option[Recipe] を取り除くなど、いくつかの異なることを行うことができます。これにより、複数のレシピを選択して渡す場合も簡単になります。 List[Recipe] でそれらをビューに追加し、それを繰り返し処理できます。

お役に立てれば。

于 2013-09-11T15:39:41.913 に答える
0

私はこれを解決する方法を考え出しましたが、それは非常にハッキーに思えますが、これを行うためのベストプラクティスでエレガントな方法を理解したいと思っています。

私の解決策 - ビューを次のように変更することにより:

@main("Site name") {

// This is a hacky way to just show the Recipe components once
@for((item, index) <- result.zipWithIndex) {
@if(index == 0) {

    <h2>---Recipe---</h2>
      RecID: @item._1 <br>
      Cuisine: @item._2<br>
      Instructions: @item._3 <br>

        <h2>---Ingredients---</h2>

    }
}

// And now we list all ingredients..
    @for((id, cuisine,instructions, quantity, units, brand, name) <- result) {
    <!--<h2>Recipe</h2>
      RecID: @id <br>
      Cuisine: @cuisine <br>
      Instructions: @instructions <br>-->
      Ingredient: @quantity @units of @brand @name<br>
  }


}

..必要な出力が得られます。

---Recipe---
RecID: 1 
Cuisine: Chinese
Instructions: Instructions here

---Ingredients---
Ingredient: 3 cloves of Generic Ginger
Ingredient: 3 slices of Generic Cucumber

確かにこれを行うためのより読みやすい方法はありますか??

于 2013-09-10T12:02:44.250 に答える