2017-02-03 4 views
0

Haben Sie ein Stück Code, das ein Produkt hinzufügt/aktualisiert und ihm auch ein oder mehrere Tags zuordnet. Tags werden tatsächlich zu einer TagGroup hinzugefügt, die dem Produkt zugeordnet ist.Scala-Slick: Nur ein Teil der Abfolge der ausgeführten Aktionen

Problem Ich bin konfrontiert ist, dass nur "Teil" von addOrUpdateProductWithTags() ausgeführt wird. Produkt wird aktualisiert oder erstellt, aber Tags werden nicht hinzugefügt. Wenn ich die letzte Abfrage kommentiere (siehe Kommentar), dann funktioniert alles. Aktivieren Sie "", um dies zu bestätigen.

lazy val pRetId = prods returning prods.map(_.id) 

def addTags(keywords: Seq[String]) = { 
    for { 
    k <- keywords 
    } yield { 
    tags.filter(_.keyword === k).take(1).result.headOption.flatMap { 
     case Some(tag) => { 
     Logger.debug("Using existing tag: " + k) 
     DBIO.successful(tag.id) 
     } 
     case None => { 
     Logger.debug("Adding new tag: " + k) 
     tags.returning(tags.map(_.id)) += Tag(k, Some("DUMMY")) 
     } 
    } 
    } 
} 

def addOrUpdateProductWithTags(prod: Product, tagSet: Seq[String]): Future[Option[Long]] = { 

    // handle add or update product 
    val prodObject = prod.id match { 
    case 0L => pRetId += prod 
    case _ => prods.withFilter(_.id === prod.id).update(prod) 
    } 

    val action = for { 
    pid <- prodObject 
    tids <- DBIO.sequence(addTags(tagSet)) 
    } yield (tids, pid) 

    val finalAction = action.flatMap { 
    case (tids, pid) => { 
     val prodId = if (prod.id > 0L) prod.id else pid.asInstanceOf[Number].longValue 
     val delAction = tagGroups.filter(_.prodId === prodId).delete 
     val tgAction = for { 
     tid <- tids 
     } yield { 
     tagGroups += TagGroup("Ignored-XX", prodId, tid) 
     } 
     delAction.flatMap { x => DBIO.sequence(tgAction) } 

     // IF LINE BELOW IS COMMENTED THEN TagGroup is created else even delete above doesn't happen 
     prods.filter(_.id === prodId).map(_.id).result.headOption 
    } 
    } 

    db.run(finalAction.transactionally) 
} 

Dies ist das Snippet in der Steuerung, von der diese Methode aufgerufen wird. Mein Verdacht ist, dass Anrufer nicht lange genug, aber nicht sicher warten ...

val prod = Prod(...) 
val tagSet = generateTags(prod.tags) 
val add = prodsService.addOrUpdateProductWithTags(prod, tagSet) 
add.map { value => 
    Redirect(controllers.www.routes.Dashboard.dashboard) 
}.recover { 
    case th => 
    InternalServerError("bad things happen in life: " + th) 
}   

Jeder Hinweis, was ist los mit der Abfrage? Stack: Scala 2.11.7, Play-Version 2.5.4, spiel glatt 2.0.0 (Slick 3.1)

+1

Haben Sie versucht, die ausgeführten SQL-Abfragen auszudrucken? '' – nmat

+0

Ja, das hat es getan, es zeigt keine Lösch- und Folgeaktionen, wenn die letzte Zeile vorhanden ist. – srvy

+0

Können Sie den Inhalt von 'addTags' anzeigen? –

Antwort

0

Endlich eine Lösung herausgefunden:

Anstelle der folgenden zwei Zeilen:

delAction.flatMap { x => DBIO.sequence(tgAction) } 
    prods.filter(_.id === prodId).map(_.id).result.headOption 

I kombiniert die Aktionen mit andthen Operatoren wie folgt:

delAction >> DBIO.sequence(tgAction) >> prods.filter(_.id === prodId).map(_.id).result.headOption 

Nun ist die gesamte Sequenz ausgeführt wird. Ich weiß immer noch nicht, was mit der ursprünglichen Lösung nicht stimmt, aber das funktioniert.

+0

die SQL-Abfragen verursacht haben könnte, die ausgeführt werden soll, sollte die letzte Zeile in der FlatAmp von finalAction sein, d. H action.flatMap {} – Archana

+0

letzte Zeile wird als finalAction zurückgegeben – Archana

Verwandte Themen