Ruby:使用Gems体验重复发生的日历事件?

Ale*_*xey 14 ruby gem calendar ruby-on-rails recurring-events

我想为我的项目找到一个ruby gem来处理符合以下要求的reccuring事件:

  • 可以处理"星期二和星期三的每周"或"上周二的每月"等模式
  • 可以计算下一次出现
  • 可以将模式序列化/反序列化为字符串以存储在数据库中
  • 序列化具有稳定的格式(即使升级后也可以加载)
  • 至少使用以下模式组件:时间,星期几,月份日期,每月的第n天;
  • 可以每天,每周,每月或间隔n天,数周或数月重复
  • 可以用自然英语表示一种模式
  • 可以从英语解析模式(可选)
  • 可以导出到一些流行的格式,如iCal(可选)
  • 可以与其他宝石/系统集成以进行日历和任务管理(可选)
  • 支持Active Record - 参数解析,验证(可选)
  • 有足够的测试,几个错误,超过1个用户:)
  • 有合理的表现

我找到了两个相关候选人:

  • 痒 - 好的是它可以解析英语.
  • Ice_Cube(+ Schedule-Attributes) - 好处是它最受欢迎并且可以导出到iCal

你能否提出一个宝石并用它描述积极和消极的经历?

也许你可以添加一些我没有提到的相关标准/要求.

PS Pease某人用1,5K +添加recurring_events标记.谢谢

Ale*_*xey 8

我最终使用Ice_Cube的原因如下:

  • 最受欢迎
  • 可以计算下一次出现
  • 可以将模式序列化/反序列化为字符串以存储在数据库中
  • 序列化具有稳定的格式(即使升级后也可以加载)
  • 至少使用以下模式组件:时间,星期几,月份日期,每月的第n天;
  • 可以每天,每周,每月或间隔n天,数周或数月重复
  • 可以从英语解析模式(可选)
  • 可以导出到一些流行的格式,如iCal(可选)

根据我的标准,这些不是由它填满的:

  • 可以用自然英语表示一种模式
  • 支持Active Record - 参数解析,验证(可选)

这个未经验证:

  • 有合理的表现

从Rails中的用户输入创建Ice_Cube :: Schedule不是很方便,但可行:

class EntryForm < FormModel

  include IceCube
  class_eval &ValidatesTimelinessSupport[{:start_date => :datetime}]

  Units = [Day = 'day', Week = 'week']
  Intervals = %w[0 1 2 3 4 5 6 7 8 9]
  Week_Days = [:sunday, :monday, :tuesday, :wednesday, :thursday, :friday, :saturday]

  Days_With_Letters = Week_Days.zip(%w[S M T W T F S])

  attr_accessible_accessors :interval, :unit, :start_date
  attr_accessible_accessors *Week_Days

  def_delegators :@model, :display_title, :schedule_yaml, :schedule_yaml=

  validates_date :start_date, :allow_blank => true
  validates_inclusion_of :unit, :in => Units
  validates_inclusion_of :interval, :in => Intervals
  validates_inclusion_of :complete, :in => %w[0 1], :allow_blank => true
  Week_Days.each { |day| validates_inclusion_of day, :in => %w[0 1], :allow_blank => true }

  before_edit {
    if not schedule_yaml.blank? and hash = YAML::load(schedule_yaml)
      schedule = Schedule.from_hash(hash)
    end

    if schedule and rule = schedule.rrules.first
      @start_date = schedule.start_date

      rule_hash = rule.to_hash
      @interval = rule_hash[:interval]

      case rule
      when DailyRule
        @unit = Day
      when WeeklyRule
        @unit = Week
        rule_hash[:validations][:day].try :each do |day_index|
          send "#{Week_Days[day_index]}=", 1
        end
      end

    else
      @start_date = Date.today
      @interval = 1
      @unit = Day
    end
  }

  before_save {
      sd = @start_date.blank? ?
          Date.today.to_all_day :
          @start_date.parse_date_in_timezone
      i = @interval.to_i
      schedule = Schedule.new(sd)


      rule = case @unit
        when Day
          Rule.daily i
        when Week
          Rule.weekly(i).day(
            *Week_Days.
            select { |day| send(day).to_i == 1 } )
      end

      schedule.add_recurrence_rule(rule)

      self.schedule_yaml = schedule.to_yaml
    end
  }
end
Run Code Online (Sandbox Code Playgroud)


Mor*_*rgz 7

和Ice_Cube一样可爱,它似乎不适合大规模调度应用程序,在这些应用程序中,您可能需要过滤100,000个事件以查看当天显示的内容.想想meetup.com

因为它全部序列化为规则字符串,过滤主要列表的唯一方法似乎是这样的:

def self.entries_on(date)
    entries = TimetableEntry.all
    entries.reject{|te|!te.schedule.occurs_on?(date)}
end
Run Code Online (Sandbox Code Playgroud)

不是很有效率.有人请认可我!! 希望我错过了一招?

也可以尝试使用上述方法,使用将来100年的日期......看起来好像ice_cube会慢慢减慢您从当前日期查询的速度.