title: Slick: CRUD extension: How to encapsulate implicit mapping:BaseColumnType[T]
body: <p>There is the following API for Slick CRUD (Slick-2.1.0, Scala-2.11.4):</p>
  
  <pre><code>trait HasId {
    type Id
    def id: Option[Id]
  }
  trait HasIdColumn[E &lt;: HasId] {
    def id: scala.slick.lifted.Column[E#Id]
  }
  trait SlickExtensions {
      val driver: scala.slick.driver.JdbcProfile
      import driver.simple._
  
      trait BaseDAO[T &lt;: Table[E], E] {
        val query: TableQuery[T]
      }
      trait HasIdActions[T &lt;: Table[E] with HasIdColumn[E], E &lt;: HasId] 
        extends BaseDAO[T, E] {
        //line L1: this implicit val is needed to execute query.filter(_.id === id)
        // what can be done in order to save the user from the necessity 
        // to override this value?
        implicit val mappingId: BaseColumnType[E#Id]
  
        def findById(id: E#Id)(implicit session: Session): Option[E] = 
            query.filter(_.id === id).firstOption
        ...
      }
  }
  </code></pre>
  
  <p>I apply this SlickExtensions as follows:</p>
  
  <pre><code>case class Entity(id: Option[Long] = None, value: String) extends HasId { 
     type Id = Long }
  
  trait EntityComponent extends SlickExtensions {
      import driver.simple._
  
      class EntitiesTable(tag: Tag) extends Table[Entity](tag, "entities") 
       with HasIdColumn[Entity] {
        def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
        def value = column[String]("value", O.NotNull)
        def * = (id.?, value) &lt;&gt;(Entity.tupled, Entity.unapply)
      }
  
      object Entities extends HasIdActions[EntitiesTable, Entity] {
        val query = TableQuery[EntitiesTable]
        /* line L2: from slick library: ImplicitColumnTypes */
        override implicit val mappingId = driver.simple.longColumnType
      }
    }
  </code></pre>
  
  <p>End point to execute queries:</p>
  
  <pre><code>val c = new EntityComponent {
      lazy val driver = play.api.db.slick.Config.driver
  }
  
  db.withSession { implicit session =&gt;
      c.Entities.findById(1) foreach println
  }
  </code></pre>
  
  <hr>
  
  <p>The main question is how to get rid of "implicit val mappingId" overriding in line L2?</p>
  
  <p>I tried to create a class:</p>
  
  <pre><code>abstract class IdImplicits[E&lt;:HasId](implicit val mappingId:BaseColumnType[E#Id])
  </code></pre>
  
  <p>and inherited it as follows:</p>
  
  <pre><code>object Entities extends IdImplicits[EntitiesTable, Entity] 
     with HasIdActions[EntitiesTable, Entity] {
        val query = TableQuery[EntitiesTable]
        //override implicit val mappingId: driver.simple.longColumnType
  }
  </code></pre>
  
  <p>However it seems to me that such approach is redundant. 
  It would be great if I could hide "implicit val mappingId" inside SlickExtensions.</p>
  
  <p><a href="https://groups.google.com/forum/#!topic/scalaquery/ISHtc8oqy3M" rel="nofollow noreferrer">Here is the link to the same question</a></p>
  
  <hr>
  
  <p><strong>UPD:</strong></p>
  
  <p>In my project, I'd like to add HasName, HasValue[V] and some other mixins to construct the following DAOs:</p>
  
  <pre><code>object EntitiesDAO extends HasIdActions 
    with HasNameActions 
    with HasValueActions with NameToIdActions with ValueToIdActions {
      ...
      override def nameToId(name:String):Option[E#Id]
      override def valueToId(value:E#ValueType):Option[E#Id]
      ...
  }
  </code></pre>
  
  <p>It leads to the following problems:</p>
  
  <p>1) implicits for BaseColumnTypes, mentioned in my topic, should be taken into consideration for HasId, HasValue mixins</p>
  
  <p>2) If implicits BaseColumnTypes are used as parameters of constructor of abstract classes then these classes can't be mixed in one EntityDAO object (<a href="https://stackoverflow.com/q/27077041/2921380">the problem is described here</a>).</p>
  
  <p>3) If one abstract class is used for each variant of EntityDAO, then we get ugly-looking combinations, for example:</p>
  
  <pre><code>abstract class IdValueNameImplicits[E &lt;: HasId with HasValue with HasName]
       (implicit val idMapper:BaseColumnType[E#Id], 
        implicit val valueMapper:BaseColumnType[E#ValueType])
  </code></pre>