2016-11-08 62 views
1

我想了解這個錯誤:斯卡拉類型中的這個「_1」是什麼?

found : row.type (with underlying type _#TableElementType) 
required: _1#TableElementType 

貌似我非常接近,但「1」 _1#TableElementType這是什麼?我可以將其中一個轉換成另一個嗎?

編輯:代碼的有用位上下文(播放+油滑):

tableObject
abstract class GenericDAO[T <: AbstractTable[_]](...) { 
    def table: TableQuery[T] 
    def insert(model: T#TableElementType) = db run (table += model) 
} 

trait TableObject[T <: AbstractTable[_]] { 
    def rowFromJson(jsObject: JsObject): T#TableElementType 
    def dao(driver: JdbcProfile, db: Database): GenericDAO[T] 
} 

// Controller Action with an instance implementing `tableObject` above: 
val tableObject = tableObjectFactory("test") 
val row = tableObject.rowFromJson(request.body.asJson.get) 
val dao = tableObject.dao(driver, db) // tableObject has a DOA extending GenericDAO 
dao.insert(row) 

object TestTable extends TableObject[Test] { 
    def dao(driver: JdbcProfile, db: Database) = new TestDAO(driver, db) 
    def rowFromJson(j: JsObject): TestRow = { TestRow(...) } 
    class TestDAO(...) extends GenericDAO[Test](driver, db) { ... } 
} 

我使用一個工廠來從URL是正確的:

object TableObjectFactory { 
    def tableObjectFactory(name: String) = { 
    name match { 
     case "test" => TestTable 
     case "projects" => ProjectsTable 
     case "people" => PeopleTable 
     ... 
    } 
    } 
} 
+1

你能分享你的代碼嗎? – BDR

+0

我添加了提供上下文的代碼。 – JulienD

+0

「tableObject」的類型究竟是什麼?你是否將它定義爲'val tableObject = TestTable'? –

回答

0

儘管它沒有說明太多,我如果我讓DAO解析請求體並插入,而不是單獨生成行對象並在其上應用其中一個DAO方法,那麼t起作用。

我得到了各種類似的錯誤,如_$1#TableElementType,_1$u#TableElementType等名稱,但我認爲它們是同一類的不同實例的編譯器別名。

因此,解決辦法是做

val j: JsValue = request.body.asJson.get 
val tableObject: TableObject[_] = tableObjectFactory(table) 
val dao = tableObject.dao(driver, db) 
val res: Future[Int] = dao.insert(j) 

其中新insert方法現在是GenericDAO抽象,並在具體的實現需要一個JsValue並解析它,然後插入:

class TestDAO(override val driver: JdbcProfile, override val db: Database) extends GenericDAO[Test](driver, db) { 
    import this.driver.api._ 

    val table = TableQuery[Test] 

    //def insert(model: TestRow) = db run (table += model) // NO! 

    def insert(j: JsValue): Future[Int] = { 
    val row = TestRow(
     (j \ "id").as[Int], 
     (j \ "name").as[String], 
     (j \ "value").as[Float], 
     (j \ "other").as[String] 
    ) 
    db run (table += row) 
    } 
} 

同時,它使得Play形式完全無用,無論如何這是一件好事。