Ruby: Как хранить и показывать день недели?
Я относительно новичок в Ruby. Мне нужно отслеживать день недели в моей модели деятельности. Код, который я до сих пор не кажется самым элегантным решением. Мне интересно, есть ли лучший способ.
До сих пор это то, что у меня есть в моей форме:
<%= form_for(@activity) do |f| %>
<div class="field">
<%= f.label :day %><br />
<%= f.select :day, [['Sunday', 0], ['Monday', 1], ['Tuesday', 2], ['Wednesday', 3], ['Thursday', 4], ['Friday', 5], ['Saturday', 6]] %>
</div>
<% end %>
И когда мне нужно отобразить день недели:
<% days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] %>
<% @activities.each do |activity| %>
<%= days[activity.day.to_i] %>
<% end %>
Как я могу сделать это лучше? Не стесняйтесь упоминать любую библиотеку/драгоценность, о которой я, возможно, и не подозреваю.
Решение:
Ruby предоставляет константу Date::DAYNAMES
, которая представляет собой массив дней недели. Мы можем повторно использовать это в нашем коде:
<%= form_for(@activity) do |f| %>
<div class="field">
<%= f.label :day %><br />
<%= f.select :day, Date::DAYNAMES.zip((0..6).to_a) %>
</div>
<% end %>
<% @activities.each do |activity| %>
<%= Date::DAYNAMES[activity.day.to_i] %>
<% end %>
Ответы
Ответ 1
Ruby Date
class уже имеет определенную константу, которая содержит имя дней в массиве: Date::DAYNAMES
.
Например, вы можете сделать что-то вроде:
days = []
Date::DAYNAMES.each_with_index { |x, i| days << [x, i] }
Я не знаю, буду ли я говорить, что это лучше, но вы можете определенно использовать то, что уже доступно вам.
Ответ 2
Самый простой способ (RoR) - использовать встроенную константу:
Date::DAYS_INTO_WEEK
# =>
{:monday=>0,
:tuesday=>1,
:wednesday=>2,
:thursday=>3,
:friday=>4,
:saturday=>5,
:sunday=>6}
Ответ 3
Чтобы это было проще, я бы:
- сохранить текстовое имя дня вместо номера в
@activity.day
- добавить постоянный DAYS, он может жить на вашей модели деятельности, но может переместиться в другое место в будущем
Тогда он будет выглядеть так:
Model
DAYS = ['monday','tuesday',...]
validates_inclusion_of :day, :in => DAYS
Вид: форма
<%= f.collection_select :day, Activity::DAYS, :to_s, :humanize %>
Вид: отображение
<%= activity.day.humanize %>
Держите его простым, и вы продляете его позже, если это необходимо:)
Ответ 4
В последних версиях вы можете определить перечисление с этой константой, а затем использовать ее для разных вещей:
В процессе миграции day_of_week является целым числом
В модели:
enum :day_of_week => Date::DAYS_INTO_WEEK
И затем вы можете использовать поиск в модели
Model.day_of_weeks.keys[0..4]
вернется [ "понедельник", "вторник", "пятница" ]
Model.monday
эквивалентно Model.where("day_of_week = ?", 'monday')
http://api.rubyonrails.org/classes/ActiveRecord/Enum.html