您如何在Rails应用程序的db / model中存储业务时间?

我正在创建一个Rails应用程序,它将存储业务的开始和结束时间。 最初,我想过简单地使用文本数据类型并让它是自由格式:

"Monday to Friday 9am to 5pm Saturday 11am to 4pm Closed Sundays" 

但是,要求已经改变,我需要根据当前日期和时间检查小时数,并在视图中显示“打开”或“关闭”。 就像是:

 class Business  open_time && Time.now < close_time end end 

那么,在存储一周中每一天的工作时间方面,解决这个问题的最佳方法是什么? 业务应该只是具有开放和关闭时间的open_locky:open_blocks(或其他)吗? 我应该把这一天存储为字符串吗?

我目前正在为客户端设置目录列表,我们希望为用户提供更大的灵活性。 所以:让用户设置几天的块:

我们有一天 (整数1-7), 开放 (时间), 关闭 (时间)和一些商店或景点有夏季和冬季开放时间,或他们休假。 根据schema.org,您必须添加valid_from(datetime)和valid_through(datetime)。

通过此设置,用户可以创建他想要的任何内容:

 # migration class CreateOpeningHours < ActiveRecord::Migration def change create_table :opening_hours do |t| t.integer :entry_id # your model reference t.integer :day t.time :closes t.time :opens t.datetime :valid_from t.datetime :valid_through end end end 

模型示例:

 class OpeningHour < ActiveRecord::Base belongs_to :entry validates_presence_of :day, :closes, :opens, :entry_id validates_inclusion_of :day, :in => 1..7 validate :opens_before_closes validate :valid_from_before_valid_through # sample validation for better user feedback validates_uniqueness_of :opens, scope: [:entry_id, :day] validates_uniqueness_of :closes, scope: [:entry_id, :day] protected def opens_before_closes errors.add(:closes, I18n.t('errors.opens_before_closes')) if opens && closes && opens >= closes end def valid_from_before_valid_through errors.add(:valid_through, I18n.t('errors.valid_from_before_valid_through')) if valid_from && valid_through && valid_from >= valid_through end end 

使用该设置,您可以轻松创建is_open? 模型中的方法。 目前我没有设置is_open? 方法,但如果有人需要,给我一个打击! 我想我会在接下来的几天里完成它。

这是最近RubyLearning 挑战的主题 – 可能会有所帮助:)

在这种情况下,如果您想要关闭业务的某些日子(例如非经常性关闭),我可能会做一些关系,也许是STI。 这是一个基本的STI示例:

 class Business < ActiveRecord::Base has_many :open_time_blocks has_many :closed_time_blocks def open?(time) # false if time is "inside" any of the closed_time_blocks # else is true if inside any of the open_time_blocks # else is false end def closed?(time) !open? end end # == Schema Information # # Table name: time_blocks # # id :integer not null, primary key # business_id :integer # type :string(255) # start_at :datetime # end_at :datetime # created_at :datetime # updated_at :datetime class TimeBlock < ActiveRecord::Base belongs_to :business end class OpenTimeBlock < TimeBlock; end class ClosedTimeBlock < TimeBlock; end 

我会说运营时间属于派对地址,应该由RFC 5455 RRULE和可选的EXRULE或EXDATE代表 。

假设你有一个派对:

“Acme,Inc。”

他们有一个PhysicalAddress:

“123 Main Street,Vancouver”

他们的地址扮演两个角色:

“销售”和“服务”

销售开放Mo-Sa 10-8,服务开放Mo-Fr 9-5

这些是RRULES:

(销售部)

 startTime:'10:00:00' endTime:'20:00:00' RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR,SA 

(服务)

 startTime:'09:00:00' endTime:'17:00:00' RRULE:FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR 

检查这些库以处理重复日期。

一旦在对象中设置了重复office_hours ,例如office_hours ,在ice_cube您可以将其查询为:

 office_hours.occurring_at?(Time.now) 

所以我发现ice_cube可以处理经常性的持续时间:

 > schedule = IceCube::Schedule.new(Time.now, :duration => 3600) > schedule.add_recurrence_rule Rule.daily > schedule.occurs_at?(Time.now + 1000) true > schedule.occurs_at?(Time.now + 1.day + 1000) true > schedule.occurs_at?(Time.now + 4000) false 

我怀疑你可以用这种方式使用ice_cube处理很多不同的情况。

顺便说一句,我正在实施类似的开放/封闭业务计划。 我很想知道你是怎么做到的,如果你有一个github回购,我们可以一起合作。