Как разбить ответ API Trello на страницы?

Я использую API Trello для извлечения досок и их карточек.

Я заметил, что на одной из досок, которые я вытягиваю, в данный момент приближается тысяча карточек, поэтому мне интересно, как разбить результаты на страницы?

Я попытался использовать атрибут since и ввести в него время обновления последней карты, но после этого я получаю нулевые результаты, поэтому, должно быть, я делаю что-то неправильно.

Документация API мало что говорит, а ответ API, который я пробовал, очень сбивает с толку:

/boards/xyz/cards?limit=1&before=2015-1-1

возвращает карточку, активность которой после указанной даты.

"dateLastActivity"=>"2015-02-03T17:51:23.253Z",

и нет другого поля даты, которое я мог бы использовать для продолжения разбиения на страницы.


person hakunin    schedule 05.01.2016    source источник
comment
Прочитайте это прежде чем спросить: stackoverflow.com/help/mcve Вы должны предоставить свой рабочий пример. Я думаю, что вам нужно разбивать страницы самостоятельно, API возвращает вам все значения. Я не могу найти атрибут since. Я нашел filter в карточках и списках, но это для другой задачи.   -  person Marcos Pérez Gude    schedule 05.01.2016


Ответы (2)


Вы правы в своей оценке. Параметры до и с момента работают с датой создания карты. Поскольку мы используем стандартные идентификаторы Mongo, вы можете получить дату создания карты из идентификатора карты. (Вот один из таких инструментов: https://steveridout.github.io/mongo-object-time /)

​ ​Для удобства Trello также позволяет передавать идентификатор карты в параметры before и since, и мы будем использовать дату для вас. Рекомендуемый способ просмотра большого набора карточек — повторить тот же запрос и использовать эти параметры для перемещения вперед или назад.

person PeEll    schedule 29.01.2016
comment
Фантастика, большое спасибо. Теперь, если бы вы также могли задокументировать это в своей документации для других, это было бы здорово :) - person hakunin; 29.01.2016
comment
Я только что попробовал это с идентификатором одной карты в качестве аргумента как до, так и после, и ответ был действительно странным. И до, и после вернули разные карты, но они также использовали одну карту (которая не была той картой, которая была параметром). Я отправил электронное письмо в службу поддержки, но, возможно, вы могли бы написать настоящую документацию, чтобы все могли получить пользу. - person hakunin; 01.02.2016

Итак, поскольку API действительно не работает так, как вы ожидаете, я по крайней мере документирую это здесь.

Я создал тестовую доску с карточками A, B, C, ..., M, чтобы протестировать ее.

Во-первых, захват всех карт работает как положено.

api.find(:boards, '56af532ae7a74a5fcac32e66').cards.map { |c| [c.name, c.id] }

=> [
 ["A", "56af53367f15b163c0e345fd"],
 ["B", "56af533783d4fccc1cce3941"],
 ["C", "56af533831727db409451c9e"],
 ["D", "56af53397bf672bb56c7c536"],
 ["E", "56af5339f5e67cf6bcc7323b"],
 ["F", "56af533ac0aa02de54ab881a"],
 ["G", "56af533b212b095266ebb506"],
 ["H", "56af533e11992f20f375fca1"],
 ["I", "56af533fc1775129aaa7028b"],
 ["J", "56af5345f81227a7a1cc3a35"],
 ["K", "56af5345e36b3d3c45b16967"],
 ["L", "56af534d964b6c4aa93d4aca"],
 ["M", "56af534e768610ff67c781ce"]
]

Примечание: порядок карт определяется не временем их создания, а их появлением на доске слева направо и сверху вниз.

Ограничение

Ладно, пора начинать пагинацию. Давайте возьмем только первую карту, хорошо?

board.cards(limit: 1).map { |c| [c.name, c.id] }

=> [["M", "56af534e768610ff67c781ce"]]

К сожалению, API возвращает последний элемент. Определенно неожиданно. Давайте поиграем с после/до следующего.

До

Давайте возьмем карту перед последней.

board.cards(limit: 1, before: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }

=> [["L", "56af534d964b6c4aa93d4aca"]]

Это работает хорошо, L предшествует M.

После

Что произойдет, если мы возьмем карту после последней, ответ должен быть пустым, верно?

board.cards(limit: 1, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }

=> [["M", "56af534e768610ff67c781ce"]]

Мммм, что? Что произойдет, если я возьму две карты?

board.cards(limit: 2, after: '56af534e768610ff67c781ce').map { |c| [c.name, c.id] }

=> [
  ["L", "56af534d964b6c4aa93d4aca"], 
  ["M", "56af534e768610ff67c781ce"]
]

Это противоречит любой логике. Тогда точно не получится пройти список от начала до конца, потому что у списка карт нет конца.

Назад к разбивке на страницы

В этом случае нам придется пройтись по картам в обратном порядке. Просто указание limit работает, так как по умолчанию мы идем в обратном порядке. (что имеет общий смысл, верно?)

api.find(:boards, '56af532ae7a74a5fcac32e66').cards(limit: 5).map { |c| [c.name, c.id] }

=> [
 ["I", "56af533fc1775129aaa7028b"], 
 ["J", "56af5345f81227a7a1cc3a35"], 
 ["K", "56af5345e36b3d3c45b16967"], 
 ["L", "56af534d964b6c4aa93d4aca"], 
 ["M", "56af534e768610ff67c781ce"]
]

Не позволяйте порядку этих предметов обмануть вас! Они по-прежнему находятся в том же порядке, в котором они появляются на доске, они не сортируются по времени создания. Если я передвину карту M в ее столбец так, чтобы она оказалась прямо над L, API вернет их в обратном порядке.

Вопрос теперь в том, как выхватить старую карту из списка? Как говорится в другом ответе, идентификаторы представляют собой отметку времени, поэтому мы просто сортируем по идентификатору, выбираем самый низкий и продолжаем разбивать на страницы.

Примечание. Если вы быстры, вы можете создать несколько карточек в течение одной секунды, поэтому идентификаторы могут быть не в правильном порядке, поскольку они просто используют количество секунд, а не микросекунд. Это не мешает нам разбивать страницы.

board.cards(limit: 5, before: '56af533fc1775129aaa7028b').map { |c| [c.name, c.id] }

=> [
  ["D", "56af53397bf672bb56c7c536"], 
  ["E", "56af5339f5e67cf6bcc7323b"], 
  ["F", "56af533ac0aa02de54ab881a"], 
  ["G", "56af533b212b095266ebb506"], 
  ["H", "56af533e11992f20f375fca1"]
]

Круто, у нас следующая страница, давайте последнюю.

board.cards(лимит: 5, до: '56af53397bf672bb56c7c536').map { |c| [c.name, c.id] }

=> [
  ["A", "56af53367f15b163c0e345fd"],
  ["B", "56af533783d4fccc1cce3941"],
  ["C", "56af533831727db409451c9e"]
]

Да, значит, последняя страница содержит меньше карт, чем лимит, поэтому мы знаем, что это последняя страница. Ура! (если бы он был равен размеру страницы, мы бы обнаружили, что следующий ответ пуст)

person hakunin    schedule 01.02.2016
comment
Это работает для небольшого набора, но есть ограничение на 1000 действий. Если вы ограничите, скажем, 500, тогда страница = 0 в порядке, страница = 1 в порядке ... но страница = 2 выдаст ошибку о том, что вы запросили 1500, а ограничение составляет 1000. /перед парами/диапазонами. Это совершенно нелогично в отношении того, как работает нумерация страниц. - person Nick; 18.07.2016
comment
Вы хотели ответить на этот ответ? Я вообще не использую нумерацию страниц, а использую в ней с/до. - person hakunin; 19.07.2016
comment
Я неправильно прочитал последний фрагмент, моя ошибка - не заметил, что вы изменили предыдущий идентификатор Trello. Вы правы в том, что вам нужно обрабатывать их в обратном порядке, используя before. То, как я решил это, использовало до и после вместе. Так что я бы оставил с тех пор как nil для начала, а затем сохранил бы с = 56af533e11992f20f375fca1 (H) после запуска. На следующем проходе я бы использовал этот водяной знак, поскольку, а также подход «до», который вы описали выше для разбивки на страницы. - person Nick; 19.07.2016