Ruby on Rails助手优化:仅显示当前及未来月份而非过去月份
针对你的需求,我们需要给原方法加上过去月份的过滤逻辑,同时建议顺便处理重复选项的问题(毕竟多个事件可能属于同一个年月,没必要重复显示)。以下是修改后的完整实现:
def select_month_tag(events) # 获取当前年月作为过滤基准 today = Date.today current_year = today.year current_month = today.month # 第一步:提取所有有效且不重复的年月组合 unique_valid_months = events.filter_map do |event| # 跳过日期无效的事件(对应你原代码里的blank判断) next if date_and_month(event.month_ref, event.year_ref).blank? [event.year_ref, event.month_ref] end.uniq # 去重,避免同一个年月出现多次 # 第二步:过滤掉过去的年月 future_and_current_months = unique_valid_months.select do |year, month| # 判断逻辑:年份大于当前年,或者同年份但月份不早于当前月 year > current_year || (year == current_year && month >= current_month) end # 开始构建HTML下拉框 html = <<-HTML <select id="filtro-mes-ano" class="event-filter selectCustom2 event_filter_select"> <option value="Filtrar por mês" disabled selected>Filtrar por mês</option> HTML # 遍历筛选后的年月生成选项 future_and_current_months.each do |year, month| formatted_label = date_and_month(month, year) # 建议给value用标准的YYYY-MM格式,方便后续处理 html += <<-HTML <option value="#{year}-#{month.to_s.rjust(2, '0')}">#{formatted_label}</option> HTML end html += '</select>' html.html_safe # Rails环境下确保HTML正确渲染 end
核心修改说明:
- 过滤逻辑的核心:通过对比事件的
year_ref和month_ref与当前年月,只保留符合条件的项——要么年份比当前晚,要么同年份但月份不早于当前月。 - 去重处理:用
uniq去掉重复的年月组合,避免下拉框里出现同一个月份多次的情况,提升用户体验。 - 代码结构优化:把筛选逻辑和HTML生成分开,让代码更易读和维护。
性能优化建议(可选):
如果你的events是ActiveRecord查询集合,最好在数据库层面先筛选,而不是拿到所有数据后再在Ruby里过滤,这样能减少内存占用:
# 在调用方法前先筛选未来及当前月份的事件 filtered_events = Event.where( "year_ref > :current_year OR (year_ref = :current_year AND month_ref >= :current_month)", current_year: Date.today.year, current_month: Date.today.month ) # 再把filtered_events传入select_month_tag方法
内容的提问来源于stack exchange,提问作者Felipe Marcon
相关产品推荐
相关产品推荐

