25

I have looked to the ends of the earth for the answer to this question. There is not much info out there on slick 2.0. Below is my code for my Addresses model, how would I have the method create return the id after it made the insert?

package models
import play.api.Play.current
import play.api.db.slick.Config.driver.simple._
import play.api.db.slick.DB

    object Addresses{
      val DB_URL:String = "jdbc:h2:mem:fls-play"
      val DB_driver:String = "org.h2.Driver"
      class Addresses(tag: Tag) extends Table[(String, String, String, String, String)](tag, "ADDRESSES"){
       def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
       def city = column[String]("CITY")
       def stateName = column[String]("STATE_NAME")
       def street1 = column[String]("STREET1")
       def street2 = column[String]("STREET2")
       def zip = column[String]("ZIP")

       def * = (city, stateName, street1, street2, zip)
      }
      val addresses = TableQuery[Addresses]

      def create(city:String, stateName:String, street1:String, street2:String, zip:String) {
        DB.withSession{ implicit session =>
           addresses += (city, stateName, street1, street2, zip)
        }
      }
    }

Thank you!

biesior
  • 55,576
  • 10
  • 125
  • 182
James Little
  • 601
  • 7
  • 24

2 Answers2

39

Try

(addresses returning addresses.map(_.id)) += (city, stateName, street1, street2, zip)

haven't tested it, but it is shown here

Martin Kolinek
  • 2,010
  • 14
  • 16
  • Thank you so much, I can't believe I missed that. – James Little Feb 20 '14 at 20:12
  • @Martin so is what you answered the body of a method call? Can't you use tupled to reduce the code somehow? I don't like how we have to repeat the columns. Hoping you could clarify where this code actually belonds? Is this in the same spot as the * = method? – Blankman May 28 '14 at 21:18
  • 1
    @Blankman if you already have a tuple of the columns you should be able to use something like `(add returning add.map(_.id)) += tuple`. If that is what you are asking. – Martin Kolinek May 29 '14 at 08:06
  • 1
    By the way, to map the result of using `returning` (eg, to only insert certain columns), you have to use map *before* using `returning`. You could then call `insert` as normal. Eg, `addresses.map(row => (row.name, row.desc)).returning(addresses.map(_.id)).insert(("Name", "Desc"))` – Kat Dec 23 '14 at 23:50
  • 1
    Why is userId (in the doc snippet) of type FixedSqlAction[Int, NoStream, Effect.Write]? How to get the id out of that? – User Jun 08 '15 at 06:54
3

If you have fields with default values you may try this

addresses.map(c => (c.city, c.stateName, c.street1)) returning addresses.map(_.id) += (city, stateName, street1)
andemi
  • 31
  • 2