2013-03-02 5 views
5

Slickでは、データベーステーブルエントリを、それらが表すケースクラスに直接投影しようとしています。私はSomeEntity3に、いくつかの静的定数及び補助メソッドを追加したいのですが、今Slickのコンパニオンオブジェクトを持つケースクラスへの<>を使ったマップ投影

case class SomeEntity3(id: Int, entity1: Int, entity2: Int) 

val SomeEntityTable = new Table[SomeEntity3]("some_entity_table") { 
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc) 
    def entity1 = column[Int]("entity1") 
    def entity2 = column[Int]("entity2") 

    def * = id ~ entity1 ~ entity2 <> (SomeEntity3, SomeEntity3.unapply _) 
} 

example in the documentationに続いて、私は<>演算子を使用してマッピングされたプロジェクションを設定します。そのために、私はコンパニオンオブジェクトを作成します。しかし、すぐに、私は

object SomeEntity3 

行を含めるとかなり野生複数行のエラーは、「代替案との>オーバーロードされたメソッド値<」について判読できない何かを言って*の定義については、ポップアップ表示されます。

コンパニオンオブジェクトはSlickの双方向マッピングにどのように関連していますか?どういうわけか私の目標を達成できますか?

答えて

8

コンパニオンオブジェクトは、通常はケースクラスにケースクラスの最初の引数リストから関数です。あなたが明示的に仲間を自分でオブジェクトについて何かを綴るようScalaのコンパイラはコンパニオンを自動生成う

case class Fnord(a: A, b: B, c: C)(d: D) 

はできるだけ早く、今

object Fnord extends ((A, B, C) => Fnord) { 
    ... 
} 

に似たオブジェクトを持っていたのであれば、コンパイラはもはや生成FunctionN延ばす。したがって、ほとんどの場合、自分で追加することをお勧めします。そのようSomeEntity3の仲間を定める意味するだろうあなたのケースでは:

object SomeEntity3 extends ((Int, Int, Int) => SomeEntity3) { 
    ... 
} 

この動作のための(長いオープン)の問題もあります: https://issues.scala-lang.org/browse/SI-3664

9

修正は非常に簡単です:ケースクラスの

def * = id ~ entity1 ~ entity2 <> (SomeEntity3.apply _, SomeEntity3.unapply _) 
+0

これは確かに、作業を行います。スペルが明示的に適用される理由についての説明が必要です。ここで問題を修正してください。 – notan3xit

+1

明示的に関数への適用(η拡張)は '(Int、Int、Int)=> SomeEntity3'、すなわちコンパニオンオブジェクトが最初にあるべき型です。より一般的には、関数オブジェクトのapplyメソッドを "新しい"関数オブジェクトに変換すると、元の関数と同じ型が得られます。 –

+0

何らかの理由で、コンパニオンオブジェクトを持っているときにscalacが混乱し、オブジェクトのapplyを持ち上げない。 – pedrofurla

1

それを行うための別の方法は、オブジェクトを有効にすることですタプルにメソッドを適用し、それを以下に示すように<>に渡します。

package models 

import play.api._ 
import play.api.libs.json._ 
import scala.slick.driver.H2Driver.simple._ 

case class User(
    name: String, 
    id: Option[Int] = None 
) 

object User { 
    implicit val format = Json.format[User] 
} 

class UserTable(tag: Tag) extends Table[User](tag, "USERS") { 
    def id = column[Int]("ID", O.PrimaryKey, O.AutoInc) 
    def name = column[String]("NAME", O.NotNull) 

    def * = (name, id.?) <> ((User.apply _).tupled, User.unapply) 
} 

object Users extends TableQuery(new UserTable(_)) { 
    val findByID = this.findBy(_.id) 
} 
0

ケースクラスの部分的に適用されたapplyメソッドは、私のセットアップとSlick 3.0では機能しません。

しかしこれは、間接的に適切なtupled方法に穴を掘る、作品:

class WidgetTable(tag: Tag) extends Table[WidgetEntity](tag, "widget_tbl") { 

    def id = column[Int]("id",O.PrimaryKey) 
    def foo = column[String]("foo") 

    override def * = (id,foo) <> ((WidgetEntity.apply _).tupled,WidgetEntity.unapply) 
} 

詳細を参照してください:https://stackoverflow.com/a/38589579/564157

関連する問題