Передать карту в скользкий фильтр и фильтровать по значениям на карте - PullRequest
0 голосов
/ 29 февраля 2020

Я новичок в scala, и я пытаюсь передать карту, т.е. Map[String, Any]("from_type" -> "Admin", "from_id" -> 1), в мой сервис для динамической c фильтрации. Я пытаюсь избежать написания своего кода следующим образом filter(_.fromType === val && _.fromId === val2)

При попытке этого примера Слайк динамически фильтрует по списку столбцов и значений

Я получаю тип несоответствие. Required Function1[K, NotInfered T] Found: Rep[Boolean]

Сервисный код:

val query = TableQuery[UserTable]

def all(perPage: Int page: Int, listFilters: Map[String, Any]): Future[ResultPagination[User]] = {

  val baseQuery = for {
   items <- query.filter( listFilters ).take(perPage).drop(page).result // <----I want to filter here
    total <- query.length.result
  } yield ResultPagination[User](items, total)
  db.run(baseQuery)
}

Код таблицы:

def fromId: Rep[Int] = column[Int]("from_id")
def fromType: Rep[String] = column[String]("from_type")

def columnToRep(column: String): Rep[_] = {
  column match {
    case "from_type" = this.fromType
    case "from_id" = this.fromId
   }
}

1 Ответ

2 голосов
/ 02 марта 2020

Ну, я бы не рекомендовал использовать конструкцию Map[String, Any], потому что при использовании Any вы теряете безопасность типов: например, вы можете по ошибке перейти к функции Map("fromId" -> "1"), и компиляция не поможет выявить проблему.

Полагаю, вам нужно передать какую-то структуру, представляющую вариативный фильтр. И Query.filterOpt может помочь вам в этом случае. Вы можете посмотреть примеры использования по адресу: https://scala-slick.org/doc/3.3.2/queries.html#sorting -and-filtering

Пожалуйста, см. Пример кода ниже:

  // Your domain filter structure. None values will be ignored
  // So `UserFilter()` - will match all.
  case class UserFilter(fromId: Option[Int] = None, fromString: Option[String] = None)

  def all(perPage: Int, page: Int, filter: UserFilter): Future[ResultPagination[User]] = {
    val baseQuery = for {
      items <- {
        query
          .filterOpt(filter.fromId)(_.fromId === _)
          .filterOpt(filter.fromString)(_.fromType === _)
          .take(perPage)
          .drop(page)
          .result
      }
      total <- query.length.result
    } yield ResultPagination[User](items, total)
    db.run(baseQuery)
  }

И это будет безопасно. Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...