我想为我的项目找到一个红宝石宝石,使用与以下要求相符的事件:
>可以处理模式,如“周二周二和周三”,或“上周二的每月”
>可以计算下一次发生
>可以将模式序列化/反序列化为字符串以存储在数据库中
>序列化具有稳定的格式(即使升级后也能加载)
>至少使用以下模式组件:时间,星期几,月的日期,月的第n个星期;
>可以每天,每周,每月或间隔n天,几周或几个月重复
>可以代表自然英语语言的模式
>可以从英语解析模式(可选)
>可以导出为一些流行的格式,如iCal(可选)
>可以与其他宝石/系统集成用于日历和任务管理(可选)
>支持Active Record – 参数解析,验证(可选)
>有足够的测试,几个bug,多1个用户:)
>性能合理
我找到了两个相关的候选人:
痒痒 – 好可以解析英语.
> Ice_Cube(Schedule-Attributes) – 最好的是它最流行,可以导出到iCal
你能建议一个宝石,并描述积极和消极的经验吗?
也许你可以添加一些相关的标准/要求,我没有提到.
附:用15K的叮叮叮叮叮叮叮叮叮….谢谢
解决方法
我最终使用
Ice_Cube,原因如下:
> Most popular
>可以计算下一次发生
>可以将模式序列化/反序列化为字符串以存储在数据库中
>序列化具有稳定的格式(即使升级后也能加载)
>至少使用以下模式组件:时间,几周或几个月重复
>可以从英语解析模式(可选)
>可以导出为一些流行的格式,如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,: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