SlickにてAutoincrementされたIDを取得して別テーブルにInsert

SlickでAutoincrementされたIDを追加時に取得し、そのIDを使用して他のテーブルにもレコードを追加する方法
例えばAccountにユーザーを追加、IDはautoincrementされるが、そのIDを利用して他のテーブルにもIDに結びついたレコードを追加したいような場合。
の方法。


環境は
  • play2.4
  • Slick3.0
  • mysql


普通にレコード追加して、そのIDを取得する方法としてはオフィシャルドキュメントに載ってるとおり

Slick3.0.3 Manual
http://slick.typesafe.com/doc/3.0.3/queries.html#inserting

val userWithId =
  (users returning users.map(_.id)
         into ((user,id) => user.copy(id=Some(id)))
  ) += User(None, "Stefan", "Zeiger")

db.action(userWithId.transactionally)

問題ははこの取得したIDを使って他のレコードを追加すること。
トランザクションが別になっても良いのであれば難しいことは何もないのだが、
同一のトランザクションで行うには次のようにすればよい。

def(account: models.Account, another: models.Another){
  val action = (
    for {
      newId <- (accountTable returning accountTable.map(_.userId) )+=account
      _ <- anotherTable += another.copy(userId = newId)
  } yield newId )
  db.action(action.transactionally)
}

4行目でレコードを追加して、autoincrementされたnewIdを確保
5行目でanotherモデルのuserIdプロパティにnewIdをセット(関数型プログラミングならコピーで。)してInsert

これで同一トランザクションで処理できる
ほかの処理を追加したい場合はforの中に追加していく形でできる


トラックバックURL  -  http://mashi.exciton.jp/archives/182/trackback