0
0

slickでラベル付きID(ユーザー定義型)を扱う

Last updated at Posted at 2024-08-15

はじめに

「プリミティブ型の多用は良くない!」という考え方から、
以下のようにshapelessを使ってモデルにラベルを付与してみました。

case class Horse(
  id:   Option[Horse.Id],
  name: String
)
object Horse {
  type Id = Long @@ Horse
}

これで、コードがわかりやすくなり、コンパイル時に不整合があれば検出してくれるので、安全性が向上した感じがします。
しかし、データベースとの入出力の際にどうなるのか...😌

というわけで、今回はPlay FrameworkとSlickを使って、ラベル付きIDを扱う方法を紹介します!

ColumnTypeを定義

マッピングを定義することで、ラベル付きIDの入出力を円滑に行うことができます。

package model

import shapeless.tag
import shapeless.tag.@@
import slick.jdbc.JdbcType
import slick.jdbc.MySQLProfile.api._

case class Horse(
  id: Horse.Id,
  name: String
)
object Horse {
  type Id = Long @@ Horse

  implicit val horseColumType: JdbcType[Horse.Id] = MappedColumnType.base[Horse.Id, Long](
    id   => id,
    long => tag[Horse][Long](long)
  )
}

リポジトリ

リポジトリでは、通常通りcolumnメソッドの型引数にラベル付きIDを指定することができます。

private class HorseTable(tag: Tag) extends Table[Horse](tag,"horse"){
 def id = column[Option[Horse.Id]]("id",O.PrimaryKey)

まとめ

思ったより簡単にラベル付き型を扱うことができました。マッピングさえ定義すれば、ユーザー定義型でも同じように対応できると思います!
ラベル付き型を使うとコードが安全になり、読みやすさも向上するので最高ですね!(少し手間がかかるけど)

ちなみに、TypeScriptでも同様のことができるのかなと調べたら、Branded Typesというものがあるようです🤔
気になります...!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0