Как бы вы построили этот ежедневный график занятий?
-
06-07-2019 - |
Вопрос
То, что я хочу сделать, очень просто, но я пытаюсь найти лучший или самый элегантный способ сделать это.Приложение Rails, которое я сейчас создаю, будет иметь расписание ежедневных занятий.Для каждого класса поля, относящиеся к этому вопросу:
- День недели
- Время начала
- Время окончания
Одна запись может быть чем-то вроде:
- день недели:Среда
- время начала:10:00 утра
- время окончания:Полдень
Также я должен отметить, что это двуязычное приложение Rails 2.2, и я использую встроенную функцию i18n Rails.На самом деле у меня есть несколько вопросов.
Что касается дня недели, следует ли мне создать дополнительную таблицу со списком дней или есть встроенный способ создания этого списка на лету?Имейте в виду, что эти дни недели должны отображаться на английском или испанском языке в представлении расписания в зависимости от языковой переменной.
При запросе расписания мне нужно будет сгруппировать и упорядочить результаты по дням недели, с понедельника по воскресенье, и, конечно же, упорядочить занятия внутри каждого дня по времени начала.
Что касается времени начала и окончания каждого класса, вы бы использовали поля даты и времени или целочисленные поля?Если последнее, как бы вы именно это реализовали?
С нетерпением жду возможности прочитать различные предложения, которые вы, ребята, предложите.
Решение
Я бы просто сохранил день недели как целое число.0 => понедельник ...6 => воскресенье (или как хотите.то есть.0 => воскресенье).Затем сохраните время начала и время окончания как Время.
Это значительно упростило бы группировку.Все, что вам нужно сделать, это отсортировать по дню недели и времени начала.
Вы можете отобразить это разными способами, но я бы сделал вот что.
Иметь такие функции, как:
@sunday_classes = DailyClass.find_sunday_classes
который возвращает все занятия на воскресенье, отсортированные по времени начала.Затем повторяйте каждый день.def find_sunday_classes find_by_day_of_week(1, :order -> 'start_time') end
Примечание:find_by, вероятно, должен иметь идентификатор в конце, но это просто предпочтение в том, как вы хотите назвать столбец.
Если вам нужна полная неделя, вызовите все семь из контроллера и просмотрите их в представлении.Вы даже можете создавать страницы с подробными сведениями для каждого дня.
- Перевод — единственная сложная часть.Вы можете создать вспомогательную функцию, которая принимает целое число и возвращает текст для соответствующего дня недели в зависимости от локального значения.
Это очень просто.Ничего сложного.
Другие советы
Если ваши данные представляют собой время, я бы сохранил их как время - в противном случае вам всегда придется преобразовывать их из базы данных, когда вы выполняете с ними операции, связанные с датой и временем.День — это избыточные данные, так как он будет частью объекта времени.
Это должно означать, что вам не нужно хранить список дней.
Если t — время, то
t.strftime('%A')
всегда будет сообщать вам день в виде строки на английском языке.Затем это может быть переведено i18n по мере необходимости.
Таким образом, вам нужно сохранить только время начала и время окончания или время начала и продолжительность.Оба должны быть эквивалентны.У меня возникнет соблазн сохранить время окончания самостоятельно, на случай, если вам понадобится манипулировать данными о времени окончания, которое, следовательно, не нужно будет рассчитывать.
Я думаю, что большая часть остального того, что вы описываете, также должна выпадать из хранения данных времени как экземпляров времени.
Заказ по дню недели и времени будет просто вопросом заказа по столбцу времени.то есть
daily_class.find(:all, :conditions => ['whatever'], :order => :starting_time)
Группировка по дням есть немного сложнее.Однако это отличный пост о том, как группировать по неделям.Группировка по дням будет аналогична.
Если вы имеете дело с нетривиальными объемами данных, возможно, лучше сделать это в базе данных с помощью find_by_sql
и это может зависеть от функций времени и даты вашей базы данных, но, опять же, сохранение данных в виде времени также поможет вам здесь.Например, в Postgresql (который я использую) получение недели занятий равно
date_trunc('week', starting_time)
который вы можете использовать в предложении Group By или в качестве значения для использования в некоторой логике цикла в рельсах.
По дням недели, если вам нужно, например.классы, которые встречаются с 09:00 до 10:00 на MWF, тогда вы можете либо использовать отдельную таблицу для дней встреч класса (с указанием идентификатора класса и DOW), либо быть злым (т. е.ненормализованные) и сохранять эквивалент массива ДОУ в каждом классе.Классический аргумент таков:
- Отдельную таблицу можно проиндексировать таким образом, чтобы поддерживать выборку, ориентированную на класс или DOW, но для того, чтобы собрать воедино всю картину для класса, потребуется немного больше усилий.
- Массив DOW проще визуализировать для начинающих программистов и немного проще кодировать, но это означает, что рассуждения о DOW требуют рассмотрения все занятия.
Если это касается только вашего личного расписания занятий, делайте то, что принесет вам желаемую пользу, и живите с последствиями;если вы пытаетесь построить настоящую систему для нескольких пользователей, я бы использовал отдельную таблицу.Все эти правила нормализации существуют не просто так.
Что касается (удобочитаемых) названий DOW, это проблема уровня представления и не должна быть в основной концепции DOW.(Предположим, вы решили переехать в Монреаль и вам нужен французский язык?Это должно быть еще одно «лицо», а не изменение базовой реализации.)
Что касается времени начала/окончания, опять же, проблема в ваших требованиях.Если все занятия начинаются и заканчиваются в пределах часа (x:00), вы, безусловно, можете использовать 0..23 в качестве часов дня.Но тогда ваша жизнь станет несчастной, как только вам придется провести этот 45-минутный семинар.Как говорилось в старой рекламе: «Заплати мне сейчас или заплати позже».
Один из подходов — определить собственную концепцию ClassTime и разделить все рассуждения о времени на этот класс.Оно может начаться с упрощенного представления (целочисленные часы 0–23 или целочисленные минуты после полуночи 0–1439), а затем «расти» по мере необходимости.