Лучший способ рассчитать непрерывную серию дней - PullRequest
3 голосов
/ 29 марта 2011

В моем приложении пользователь has_many Жесты.Как правильно рассчитать, сколько последующих дней Пользователь делал Жестами?

Прямо сейчас я делаю это, как показано ниже, и работает так, как я хочу.Но ясно, что это не масштабируется.

class User < ActiveRecord::Base

  # ...

  def calculate_current_streak
    return 0 unless yesterday = gestures.done_on_day(Date.today-1)
    i = 0
    while gesture = self.gestures.done_on_day(Date.today - (i+1).days).first
      i += 1
    end
    i += 1 if gestures.done_on_day(Date.today).first
    i
  end

end 

Спасибо!Особые замечания тому, кто может работать таким образом, чтобы отслеживать только рабочие дни:)

1 Ответ

3 голосов
/ 29 марта 2011

Подумайте об этом следующим образом:

Длина полосы эквивалентна количеству (рабочих) дней, прошедших с последнего (рабочего) дня, когда пользователь вообще не использовал жесты, верно?

Таким образом, решение сводится к вычислению самого последнего дня, когда пользователь не сделал жест.

Чтобы сделать это проще всего, есть хитрость, которую используют многие администраторы БД:они создают таблицу БД с всеми датами (скажем, все даты с 2000 по 2100 год).В таблице должно быть только поле даты, но вы можете добавить логическое поле, чтобы отмечать нерабочие дни, такие как выходные и праздничные дни.Такая таблица может быть полезна при лотах запросов, и вам нужно только создать и заполнить ее один раз.( Вот более подробная статья о таких таблицах, написанная для MS SQL, но в любом случае проницательная.)

Имея эту таблицу (назовем ее dates), вы можете рассчитать свои предварительныедата строки с использованием чего-то вроде (псевдо-SQL):

SELECT d.date
FROM dates d
LEFT JOIN gestures g ON d.date = g.date AND g.user_id = <put_user_id_here>
WHERE d.date < TODAY() AND g.date IS NULL AND d.work_day = TRUE
ORDER BY d.date DESC
LIMIT 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...