В некоторых проектах требуется дать возможность пользователю настроить правила для повторяющихся событий. Иногда правила событий могут быть достаточно сложными, к примеру, “каждый предпоследний день месяца” или “каждую вторую пятницу месяца до определенной даты“. Для решения подобных задач можно успешно применять gem ice_cube.

Gem ice_cube позволяет задавать правила для повторяющихся событий используя API на подобие iCalendar и сериализовать/десериализовать расписания в форматах YAML и Ruby Hash. Ice_cube позволяет хранить только одно расписание, а не генерировать сразу сотни событий на перед. Мы выбрали ice_cube из-за удобного и гибкого API, постоянных обновлений и исправлений ошибок, популярности среди других разработчиков.

Инсталяция gem:

gem install ice_cube

Для создания расписания необходимо воспользоваться классом IceCube::Schedule:

require 'rubygems'
require 'ice_cube'

include IceCube

# Параметры:
# - дата/время начала расписания
# {
#  :duration => 3600  - продолжительность в секундах
#  :end_time => Time.now + 3600 - время окончания
# }
schedule = Schedule.new(Date.today)  

# Добавить повторение
schedule.add_recurrence_time(Date.today)
# Добавить исключение
schedule.add_exception_time(Date.today + 1)

Для создания правил повторения служит класс IceCube::Rule. Ice_сube поддерживает правила для ежедневных, еженедельных, ежемесячных, ежегодных, ежечасных, ежеминутных и ежесекундных повторений. Несколько примеров использования (более полный список примеров можно найти на странице проекта):

# Каждый 4-ый день
schedule.add_recurrence_rule Rule.daily(4)

# Каждую вторую неделю, в понедельник и пятницу
schedule.add_recurrence_rule Rule.weekly(2).day(:monday, :friday)

# Ежемесячно 10, 20 числа, и в последний день месяца
schedule.add_recurrence_rule Rule.monthly.day_of_month(10, 20, -1)

# Каждый месяц, в первый понедельник и последний вторник
schedule.add_recurrence_rule Rule.monthly.day_of_week(
 :monday => [1],
 :tuesday => [-1]
)

# Каждый год, на 50 день и на 100 день с конца
schedule.add_recurrence_rule Rule.yearly.day_of_year(50, -100)

Несколько правил можно комбинировать в одном расписании, в том числе и исключающие правила:

# Каждый 4-ый день / исключая понедельники и пятницы
schedule.add_recurrence_rule Rule.daily(4)
schedule.add_exception_rule Rule.weekly.day(1, 5)

Для правил можно устанавливать ограничения по количеству повторов и до определенной даты:

# Каждый 2-ой день, десять раз
schedule.add_recurrence_rule Rule.daily(2).count(10)

# Каждый 2-ой день, до конца месяца
schedule.add_recurrence_rule Rule.daily(2).until(Date.today.next_month - Date.today.day)

Теперь, наверное, самое интересное — запросы к расписанию:

# Все случаи повторений
schedule.all_occurrences

# Все случаи повторений до определенного времени
schedule.occurrences((Date.today + 5).to_time)

# Произойдет в определенное время
schedule.occurs_at?(Time.now)

# Произойдет в определенный день
schedule.occurs_on?(Date.today)

# Произойдет в промежутке времени
schedule.occurs_between?(Time.now, (Date.today + 5).to_time)

# Первые случаи повторения
schedule.first
schedule.first(3)

# Следующий случий повторения
schedule.next_occurrence
# Следующие 3 случая повторения
schedule.next_occurrences(3)

# Оставшиеся случаи повторения
schedule.remaining_occurrences

Сериализация данных в форматы YAML/HASH/iCal:

# YAML
yaml = schedule.to_yaml
Schedule.from_yaml(yaml)

# Hash
hash = schedule.to_hash
Schedule.from_hash(hash)

# iCalendar
schedule.to_ical

Мы используем gem ice_cube для реализации календаря повторяющихся событий вместе с FullCalendar и DelayedJob, пример использования можно посмотреть на этой странице.

Некоторые примеры для этой статьи взяты из официальной документации. Если у Вас есть вопросы или замечания, буду рад на них ответить.

Ссылки:


Тэги dev, ice_cube, ruby
Опубликовано в 02 Декабрь 2012, 12:51
Изменен в 09 Декабрь 2012, 12:58

comments powered by Disqus