2012-10-18 4 views
8

に依存して抽象クラスやトレイトを定義します。は、私はこの劇の枠組み2コード(簡体字)を持つ暗黙の

あなたが期待するように、私はすべてのコントローラのコードのこの種を持っているので、私は形質に基本的な動作を抽出したいのですが、このような何か:

abstract class EntityController[A<:Entity] extends Controller { 
    val companion: EntityCompanion 
    val name = "entity" 

    def list = Action { request => 
    Ok(toJson(companion.find(request.queryString))) 
    } 
    def show(id: Long) = Action { 
    companion.findById(id).map { entity => 
     Ok(toJson(entity)) 
    }.getOrElse(JsonNotFound("%s with id %s not found".format(name, id))) 
    } 
} 

しかし、私は次のエラーを取得します:

[error] EntityController.scala:25: No Json deserializer found for type List[A]. 
[error] Try to implement an implicit Writes or Format for this type. 
[error]  Ok(toJson(companion.find(request.queryString))) 
[error]   ^
[error] EntityController.scala:34: No Json deserializer found for type A. 
[error] Try to implement an implicit Writes or Format for this type. 
[error]  Ok(toJson(entity)) 
[error]    ^

私は

暗黙の WritesEntityController特性(または抽象クラスを継承 EntityController)を実装するクラスによって実装されることを伝える方法がわかりません

- 編集

これまでのところ、今、私はこのようにそれをやっている:

abstract class CrudController[A <: Entity](
    val model: EntityCompanion[A], 
    val name: String, 
    implicit val formatter: Format[A] 
) extends Controller { 

この

object CrudIdeaTypes extends CrudController[IdeaType](
    model = IdeaType, 
    name = "type of idea", 
    formatter = JsonIdeaTypeFormatter 
) 

のようにそれを使用する私は、Scalaは自動的に使用してそれを選ぶために得るcould't暗黙のうちに。私は、このインポートを試みたが、それはあなた自身が暗黙的に定義するためのcontrolerクラスをしたい場合は、単に抽象的、暗黙的な値を宣言し、派生クラスでそれらを定義

import formatters.json.IdeaTypeFormatter._ 
+0

+1、Playで共通のCRUD操作を抽象化する方法は同じと思っています。あなたのケースであるJSONレスポンスは、JSONとviews.htmlのコンテンツ+認証が混在する場合よりも簡単です。ロットのoの定型文... – virtualeyes

答えて

7

を動作しませんでした。

abstract class EntityController[A<:Entity] extends Controller { 
    protected implicit def entityWriter: Writes[A] 
    protected implicit def entityListWriter: Writes[List[A]] 
    ...  
} 

class MyEntity extends Entity { 
    ... 
} 

class MyEntityController extends EntityController[MyEntity] { 
    protected def entityWriter: Writes[MyEntity] = ... 
    protected def entityListWriter: Writes[List[MyEntity]] = ...  
} 

しかし、それは彼らがコンパイラはインポートせずに、自動的にそれらを見つけることができるように、一般的に、あなたのエンティティのコンパニオンオブジェクトで、コントローラの外にこれらの暗黙を定義することがはるかに実用的です。その後 、EntityControllerのコンストラクタに暗黙の値を渡す:

abstract class EntityController[A<:Entity](implicit entityWriter: Writes[A], entityListWriter: Writes[List[A]]) extends Controller { 
    ...  
} 

class MyEntity extends Entity { 
    ... 
} 
object MyEntity { 
    protected implicit def entityWriter: Writes[A] 
    protected implicit def entityListWriter: Writes[List[A]] 
} 

class MyEntityController extends EntityController[MyEntity] { 
    ... 
} 

最後の注意を、[MyEntity]リストに暗黙的には、(これだけMyEntityための暗黙のは明示的に定義する必要があるであろう)は、おそらく不要です。私はチェックしていませんが、通常、この "typeclassパターン"を使用する場合、 フレームワークは、Tに対して暗黙的であれば、各List [T]に対して暗黙的に定義しています。 。

関連する問題