2012-10-02 18 views
6

Ho dato un'occhiata allo computer-database sample e ho notato che per riutilizzare il parser del computer, il metodo list usa il parser Computer.withCompany, che restituisce una tupla di (Computer, Società)come riutilizzare un parser anorm in playframework 2.0 con scala

Nel caso devo gestire, invece di un riferimento alla id del computer voglio avere un oggetto di computer, come questo

caso classe computer (id: Pk [ Long] = NotAssigned, name: String, introdotto: Option [Date], fuori produzione: Option [Date], company: Company)

quindi pensavo ing come posso ottenere qualcosa di simile alla seguente (è seudocode, ovviamente)

val simple = { 
    get[Pk[Long]]("computer.id") ~ 
    get[String]("computer.name") ~ 
    get[Option[Date]]("computer.introduced") ~ 
    get[Option[Date]]("computer.discontinued") ~ 
    get[Company]("company.*") map { 
    case id~name~introduced~discontinued~company => Computer(id, name, introduced, discontinued, company) 
    } 
} 

Ovviamente, la parte difficile sarebbe come risolvere getCompany

qualche idea ???

risposta

5

devo un'entità Idea e un'entità IdeaType (è come Computer and Company, nell'esempio computer di database)

case class IdeaTest(
    val id: Pk[Long]   = NotAssigned, 
    val name: String   = "unknown idea", 
    val description: String = "no description", 
    val kind: IdeaType  = IdeaType() 
) 

case class IdeaType (
    val id: Pk[Long] = NotAssigned, 
    val name: String = "unknown idea type", 
    val description: String = "no description" 
) 

mi definiscono un TypeParser

val typeParser: RowParser[IdeaType] = { 
    get[Pk[Long]]("idea_type.id") ~ 
    get[String]("idea_type.name") ~ 
    get[String]("idea_type.description") map { 
    case id~name~description => IdeaType(
     id, name, description 
    ) 
    } 
} 

E la prima cosa che ho provato è stato:

val ideaParser: RowParser[IdeaTest] = { 
    get[Pk[Long]]("idea.id") ~ 
    get[String]("idea.name") ~ 
    get[String]("idea.description") ~ 
    typeParser map { 
    case id~name~description~ideaType => IdeaTest(
     id, name, description, ideaType 
    ) 
    } 
} 

Anche se è compilato ok, ha sempre problemi di caricamento l'ideaType.

Alla fine, ho dovuto definire un'ideaParser senza ideaType e comporre con un typeParser:

val typeParser: RowParser[IdeaType] = { 
    get[Pk[Long]]("idea_type.id") ~ 
    get[String]("idea_type.name") ~ 
    get[String]("idea_type.description") map { 
    case id~name~description => IdeaType(
     id, name, description 
    ) 
    } 
} 

val ideaWithTypeParser = ideaParser ~ typeParser map { 
    case idea~kind => (idea.copy(kind=kind)) 
} 

e questo è il codice utilizza:

def ideaById(id: Long): Option[IdeaTest] = { 
    DB.withConnection { implicit connection => 
    SQL(""" 
     select * from 
     idea inner join idea_type 
     on idea.idea_type_id = idea_type.id 
     where idea.id = {id}"""). 
     on('id -> id). 
     as(ideaParser.singleOpt) 
    } 
} 

L'unico problema che vedere, è che devo creare l'oggetto IdeaTest in uno stato incoerente (senza ideaType) e quindi copiarlo su un'altra istanza con l'IdeaType corretto.

+1

Questa risposta è stata davvero utile e ha contribuito a consolidare la mia comprensione della composizione dei parser, grazie! – EdgeCaseBerg

Problemi correlati