Dave M
Dave M

Reputation: 418

Implicit Conversion of Case Classes Issues

I am trying to implicitly convert one case class to another case class, but cannot get the code to work. My editor is giving me the error that Seq[LegacyPhase] doesn't convert to expected Seq[Phase]. Can anyone point me in the direction? Thanks in advance!

implicit def legacyToDashboardBrand(brand: LegacyDashboardBrand)(implicit session: Session): DashboardBrand = {
  val phaseSeq: Seq[Phase] = (for { phaseDataset <- dashboardPhasesQ if phaseDataset.brandId === brand.id
  } yield phaseDataset).list.toSeq
  DashboardBrand(id = brand.id, projectId = brand.projectId, name = brand.name, currentPhase = brand.currentPhase, phases = phaseSeq)
}

implicit def legacyToDashboardPhase(phase: LegacyPhase): Phase = {
  Phase(id = phase.id, brandId = phase.brandId, title = phase.title, steps = Seq())
}

Edit: If I do the second implicit conversion line in the first implicit conversion definition it works.

implicit def legacyToDashboardBrand(brand: LegacyDashboardBrand)(implicit session: Session): DashboardBrand = {
  val legacyPhaseSeq = (for { 
    phaseDataset <- dashboardPhasesQ if phaseDataset.brandId === brand.id
  } yield phaseDataset).list.toSeq
  val phaseSeq: Seq[Phase] = legacyPhaseSeq.map(phase => 
    Phase(id = phase.id, brandId = phase.brandId, title = phase.title, steps = Seq())
  )

  DashboardBrand(id = brand.id, projectId = brand.projectId, name = brand.name, currentPhase = brand.currentPhase, phases = phaseSeq)
}

Upvotes: 0

Views: 211

Answers (1)

Peter Neyens
Peter Neyens

Reputation: 9820

Your second solution (with the duplicated code) works because you explicitly convert the Seq[LegacyPhase] to a Seq[Phase].

You could achieve the same result, by adding an implicit parameter in your firstlegacyToDashboardBrand function for your LegacyPhase => Phase conversion function :

implicit def legacyToDashboardBrand(
  brand: LegacyDashboardBrand
)(implicit 
  session: Session,
  phaseConv: LegacyPhase => Phase
): DashboardBrand = {
  val phaseSeq: Seq[Phase] = (for { 
    phaseDataset <- dashboardPhasesQ if phaseDataset.brandId === brand.id
  } yield phaseDataset).list.map(phaseConv).toSeq
  DashboardBrand(
    id = brand.id, projectId = brand.projectId, name = brand.name,
    currentPhase = brand.currentPhase, phases = phaseSeq
  )
}

This way your LegacyDashboardBrand => DashboardBrand conversion function, uses your LegacyPhase => Phase conversion function.

Note: I don't think that it is a good idea to query a database in a implicit conversion function. Implicit conversions are quite "magical" themselves and make your code more difficult to understand, adding side effects like querying a database would only make it more magical.

Upvotes: 1

Related Questions