Created
August 21, 2019 04:07
-
-
Save tbcooney/afb42c034ec82a7aceff4f7257440185 to your computer and use it in GitHub Desktop.
Serialization TimeOfDay with Rails and jsonb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Supplies TimeOfDay class that includes parsing, strftime, comparison, and arithmetic | |
gem 'tod', '~> 2.2' | |
ActiveRecord::Schema.define do | |
add_column :businesses, :force => true do |t| | |
t.jsonb :business_hours | |
end | |
end | |
### It turns out you need to set the business_hours to nil, and then Rails will take care of setting the attributes. | |
### I was previously setting the migration to include default: '{}', null: false and receiving a | |
### IndexError (string not matched) error | |
class Business < ActiveRecord::Base | |
store_accessor :business_hours, :sunday_opens_at, :sunday_closes_at, | |
# ... | |
serialize :sunday_opens_at, Tod::TimeOfDay | |
serialize :sunday_closes_at, Tod::TimeOfDay | |
# ... | |
end | |
### Using a store accessor allows you to specify the keys you want to access directly without referencing the JSONB field | |
### Note: I had an issue declaring serialize before the store accessor | |
module ApplicationHelper | |
def time_select_options(step=15) | |
tod = Tod::TimeOfDay.new 0 | |
times = [] | |
96.times do | |
times << [tod.strftime("%l:%M %P"), tod] | |
tod = tod + step.minutes | |
end | |
times | |
end | |
end | |
<%= form_with(model: storage_property) do |form| %> | |
<% I18n.t('date.day_names').each_with_index do |day, wday| %> | |
<td class="day"> | |
<div class="form-group"> | |
<%= form.label :"#{day.downcase}_opens_at" %> | |
<%= form.select :"#{day.downcase}_opens_at", time_select_options, label: "Open Time", include_blank: "Closed" %> | |
</div> | |
<div class="form-group"> | |
<%= form.select :"#{day.downcase}_closes_at", time_select_options, label: "Close Time", include_blank: "Closed" %> | |
</div> | |
</td> | |
<% end %> | |
<% end %> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment