2012-10-02 78 views
6

He estado echándole un vistazo al computer-database sample y noté que para reutilizar el analizador de computadora, el método de lista utiliza el analizador Computer.withCompany, que devuelve una tupla de (Computer, Company)cómo reutilizar un analizador de anorm en playframework 2.0 con scala

En el caso que tengo que manejar, en lugar de una referencia a la identificación de la computadora que desea tener un objeto de equipo, de esta clase del ordenador

caso (id: Pk [ Long] = NotAssigned, name: String, introducido: Option [Date], discontinued: Option [Date], company: Company)

así que estaba pensando ing cómo puedo lograr algo como lo siguiente (que es seudocode, por supuesto)

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) 
    } 
} 

Obviamente, la parte difícil sería la forma de resolver getCompany

alguna idea ???

Respuesta

5

que tienen una entidad Idea y una entidad IdeaType (que es como la computadora y de la compañía, en el ejemplo de la base de datos informática)

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" 
) 

que definen 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 
    ) 
    } 
} 

Y lo primero que intentado fue:

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 
    ) 
    } 
} 

A pesar de que compila bien, siempre tiene problemas para cargar el tipo de idea.

Al final, tuve que definir un ideaParser sin ideaType y componer 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)) 
} 

y este es el código de usarlo:

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) 
    } 
} 

El único problema que ver, es que tengo que crear el objeto IdeaTest en un estado incoherente (sin ideaType) y luego copiarlo en otra instancia con el IdeaType correcto.

+1

Esta respuesta fue realmente útil y ayudó a solidificar mi comprensión de la composición de analizadores, ¡gracias! – EdgeCaseBerg

Cuestiones relacionadas