Я изучаю scala, playframework и slick, но я нашел проблему. Я пытаюсь создать простой CRUD с контроллерами списков, которые получают настраиваемое поле фильтра, некоторые данные разбивки на страницы (размер и число страниц) и Seq строковых кортежей с именем поля и порядком (asc или desc) и все работает нормально, за исключением порядка по seq, я не могу сделать заказ динамическим.Динамический порядок по scala slick с несколькими столбцами
Я получил базовую структуру от Scadiddle blog. Итак, основной код выглядит следующим образом:
У меня есть основной цвет модели:
case class Color(
id: Int,
name: String)
Это простое определение таблицы:
class ColorsTable(tag: Tag) extends Table[Color](tag, "color") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name) <> ((Color.apply _).tupled, Color.unapply)
}
В моем репо у меня есть метод поиска :
def findAll(searchTerm: Option[String], page: Int, top: Int, sortsBy: Seq[(String, SortDirection)]): Future[Seq[Color]] = {
var query = searchTerm match {
case Some(term) => colors.filter(_.name like s"%$term%")
case _ => colors
}
val offset = (page - 1) * top
// This is building the sort clause, matching on each column in the sort
sortsBy.foreach {
sortTuple =>
val (sortColumn, sortDirection) = sortTuple
query = query.sortBy(sortColumn match {
case "id" => if (sortDirection == Desc) _.id.desc else _.id.asc
case _ => if (sortDirection == Desc) _.name.desc else _.name.asc
})
}
// The "list" method actually executes the query
val colorsQuery = query.drop(offset).take(top).result
db.run(colorsQuery)
}
Проблема заключается в том, что я вызываю метод поиска с помощью этой последовательности:
val sortsBy = Seq[(String, SortDirection)](("name", Desc), ("id", Asc))
colorService.getColors(None, 1, 10, sortsBy).map(colorList => Ok(Json.toJson(colorList)))
Этот запрос генерируется:
select "id", "name" from "color" order by "id", "name" desc limit 10 offset 0
Как вы можете видеть, порядок SortBy был перевернутый (идентификатор, а затем имя, а не имя и идентификатор в виде последовательности).
Если я использую кортеж вместо этого Еогеаспа порядок уважается:
query = query.sortBy(
s => (s.name.desc, s.id.asc)
)
Но нет никакого способа для создания динамического размера кортежа. Для того, чтобы добавить еще несколько confusionm другую вещь, которая вызывает у меня проблемы в пятно документации this part:
Имейте в виду, что один ORDER BY с несколькими столбцами не эквивалентно многократным .sortBy но требует к одному .sortBy звоните проходящий кортеж
Итак, на самом деле можно ли использовать foreach и объединить заказы? Или это потому, что это ограничение, что порядок отменяется?
В случае, если для сортировки могут использоваться только кортежи, как я могу достичь порядка динамического размера?
PD: Спасибо за внимание и извините за плохой английский
EDIT:
Спасибо за быстрый ответ, я попробовал ваш код и выглядит хорошо, к сожалению, я почти не идея как это работает :((scala - очень хороший, но трудный для изучения язык: S).
Когда я увидел Higher Kinded Type Should be Enabled
, я просто испугался, ища ответы this не дал мне большой надежды, чтобы получить легкое понимание, надеюсь, когда я закончу Программирование в Scala, 3-я книга, у меня будет больше понимания и знаний о том, что черт возьми.
Еще один вопрос, является ли это эквивалентом делать несколько вызовов sortBy? как это сравнить с использованием кортежа? Я до сих пор путает эту часть скользких документов:
один ORDER BY с несколькими столбцами не эквивалентен многократным .sortBy но вызывает к одному вызову .sortBy прохождения кортежа
Я проверил метод и добавив обратное к seq, чтобы он работал нормально, конечно, не как функциональный и красивый, как ваш код, поэтому я буду использовать ваше предложение и работать над тем, чтобы сделать остальные фильтры с помощью помощников и избегать vars , (да, в другой части я все еще использую var, но я сделаю все более приятным, когда узнаю больше о Scala).
Исповедь: после более чем восьми лет программирования на нескольких языках (от JavaScript до Java, C#, Python и других), я должен повторить, Scala выглядит красивым, но очень сложным языком, но я не буду отказываться от обучения это
Я только что пробовал ваш код и отлично работает, я редактировал свой вопрос, чтобы добавить некоторые замечания, потому что раздел комментариев очень ограничен – rekiem87