Rails关联模型查询:获取Schedtimeranges中为true的星期并生成Ice_Cube规则
Rails模型关联与Ice_Cube重复规则实现方案
问题梳理
- Scheduleevent模型与Schedtimeranges为
has_many关联,Schedtimeranges包含start_time、end_time及周日至周六的布尔字段(选中日期值为true) - 需实现:提取值为true的星期存入数组传入Ice_Cube,同时获取对应
start_time、end_time - 需解决的具体问题:模型关联筛选星期字段、修正三处代码报错
模型关联与星期字段筛选
Scheduleevent已正确配置关联:
has_many :schedtimeranges, inverse_of: :scheduleevent accepts_nested_attributes_for :schedtimeranges, allow_destroy: true
要筛选每个Schedtimeranges记录中值为true的星期字段,可在Scheduleevent模型中添加实例方法:
# Scheduleevent模型 def active_weekdays_per_timerange schedtimeranges.map do |timerange| # 定义所有星期布尔字段名 weekday_fields = %w[sunday monday tuesday wednesday thursday friday saturday] # 筛选当前记录中值为true的字段名 active_days = weekday_fields.select { |field| timerange.send(field) } # 返回包含时间和激活星期的哈希 { start_time: timerange.start_time, end_time: timerange.end_time, active_weekdays: active_days } end end
代码报错修正
1. 报错no method schedtimeranges
原代码错误:将timeranges定义为类方法(def self.timeranges),但schedtimeranges是实例关联方法,只能被Scheduleevent实例调用。
修正方案:改为实例方法,并利用已有的关联查询,无需手动拼接scheduleevent_id条件:
# Scheduleevent模型中定义实例方法 def timeranges # 获取Schedtimeranges表的布尔字段名 schedtimeranges.columns.select { |c| c.type == :boolean }.map(&:name) end # 使用方式(在Scheduleevent实例中) weekdays = self.timeranges
2. 无法筛选值为true的记录
原代码错误:columns是获取表结构的字段信息,而非记录的实际值,因此无法筛选true的记录。
修正方案:遍历关联的Schedtimeranges记录,检查每个布尔字段的实际值:
# 在Scheduleevent实例中调用 weekdays = schedtimeranges.flat_map do |timerange| %w[sunday monday tuesday wednesday thursday friday saturday].select do |field| timerange.send(field) end end
3. 创建weekly规则时报错undefined method map
原代码错误:self是Scheduleevent实例,不能直接调用map;且逻辑混淆,未正确遍历schedtimeranges记录。
修正方案:遍历每个Schedtimeranges记录,提取激活星期并生成Ice_Cube规则:
schedule = IceCube::Schedule.new(start) case orule when 'daily' schedule.add_recurrence_rule IceCube::Rule.daily(1).until(end_date.to_time) when 'weekly' # 遍历每个时间范围记录 active_weekdays_per_timerange.each do |timerange_data| # 将星期字符串转为Ice_Cube需要的符号 day_symbols = timerange_data[:active_weekdays].map(&:to_sym) # 添加每周重复规则 schedule.add_recurrence_rule IceCube::Rule.weekly(1).day(day_symbols).until(end_date.to_time) end end
示例输出(中文)
对应选中日期的输出示例:07:00 上午, 14:00 下午, 周一, 周四, 周五
内容的提问来源于stack exchange,提问作者spacerobot
相关产品推荐
相关产品推荐

