You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails应用CSV导出无法随日期范围筛选更新问题求助

Rails CSV导出日期筛选不生效问题修复

问题现象

Rails应用的索引视图带有日期筛选器,默认渲染今日数据范围,页面筛选功能正常,但导出CSV时始终使用初始默认日期的数据——即便页面已通过筛选更新了@wash_orders,导出的CSV仍沿用初始日期范围的结果。

问题代码

def index
    @wash_orders = policy_scope(WashOrder)
    if params[:start_date].present? && params[:end_date].present?
      start_date = Date.parse(params[:start_date])
      end_date = Date.parse(params[:end_date])
      start_time = Time.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, "+00:00")
      end_time = Time.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, "+00:00")
    else
      today = (Time.now - 6.hours).to_date
      start_time = today.beginning_of_day
      end_time = today.end_of_day
    end
    start_time += 6.hours
    end_time += 6.hours
    @wash_orders = WashOrder.where(created_at: start_time..end_time).order(created_at: :asc)
    respond_to do |format|
      format.html
      format.csv { send_data to_csv(@wash_orders ), filename: "WO-#{Time.now.strftime('%y%m%d')}.csv" }
    end
  end

private

def to_csv(wash_orders)
    attribs = [:id, :created_date, :created_time, :closed_date, :closed_time, :created_by, :time_formated, :tool_sap, :tool_alias, :tool_bu]
    if wash_orders && wash_orders.any?
      CSV.generate(headers: true) do |csv|
        csv << attribs
        wash_orders.each do |order|
          csv << attribs.map do |attr|
            case attr
            when :created_date
              order.created_at.in_time_zone('America/Mexico_City').strftime("%Y-%m-%d")
            when :created_time
              order.created_at.in_time_zone('America/Mexico_City').strftime("%H:%M:%S")
            when :closed_date
              if order.closed_at.present?
                order.closed_at.in_time_zone('America/Mexico_City').strftime("%Y-%m-%d")
              else
                ""
              end
            when :closed_time
              if order.closed_at.present?
                order.closed_at.in_time_zone('America/Mexico_City').strftime("%H:%M:%S")
              else
                ""
              end
            when :tool_sap
              order.tool.sap
            when :tool_alias
              order.tool.alias
            when :tool_bu
              order.tool.bu
            when :time_formated
              if order.time.present?
                order.formatted_time
              else
                ""
              end
            else
              order.send(attr)
            end
          end
        end
      end
    else
      CSV.generate(headers: true) do |csv|
        csv << attribs
      end
    end
  end

问题根源

核心问题是CSV导出请求未携带日期筛选参数:页面筛选是通过表单提交给format.html的请求,但导出CSV的默认链接(如<a href="/wash_orders.csv">)不会自动带上当前页面的start_date和end_date参数,导致CSV请求进入else分支,使用默认日期范围生成数据。

此外,代码中先执行@wash_orders = policy_scope(WashOrder)后直接覆盖为WashOrder.where(...),虽不影响功能,但可优化为结合权限控制的查询逻辑。

修复方案

1. 让CSV导出链接携带筛选参数

在视图的CSV导出链接中,传递当前页面的start_date和end_date参数:

<%= link_to '导出CSV', wash_orders_path(format: :csv, start_date: params[:start_date], end_date: params[:end_date]) %>

这样CSV请求会带上用户选择的日期参数,后端就能正确筛选数据。

2. 优化查询逻辑(可选)

将权限控制与筛选条件结合,避免变量覆盖:

def index
  # 初始化带权限控制的基础查询
  wash_orders_query = policy_scope(WashOrder)

  if params[:start_date].present? && params[:end_date].present?
    start_date = Date.parse(params[:start_date])
    end_date = Date.parse(params[:end_date])
    start_time = Time.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, "+00:00")
    end_time = Time.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, "+00:00")
  else
    today = (Time.now - 6.hours).to_date
    start_time = today.beginning_of_day
    end_time = today.end_of_day
  end

  start_time += 6.hours
  end_time += 6.hours

  # 应用筛选条件到权限控制后的查询
  @wash_orders = wash_orders_query.where(created_at: start_time..end_time).order(created_at: :asc)

  respond_to do |format|
    format.html
    format.csv { send_data to_csv(@wash_orders), filename: "WO-#{Time.now.strftime('%y%m%d')}.csv" }
  end
end

3. 添加日期参数验证(可选,增强鲁棒性)

避免日期格式错误导致异常,添加异常捕获:

def index
  wash_orders_query = policy_scope(WashOrder)
  start_time, end_time = if params[:start_date].present? && params[:end_date].present?
    begin
      start_date = Date.parse(params[:start_date])
      end_date = Date.parse(params[:end_date])
      [
        Time.new(start_date.year, start_date.month, start_date.day, 0, 0, 0, "+00:00"),
        Time.new(end_date.year, end_date.month, end_date.day, 23, 59, 59, "+00:00")
      ]
    rescue ArgumentError
      # 日期格式错误时使用默认值
      today = (Time.now - 6.hours).to_date
      [today.beginning_of_day, today.end_of_day]
    end
  else
    today = (Time.now - 6.hours).to_date
    [today.beginning_of_day, today.end_of_day]
  end

  start_time += 6.hours
  end_time += 6.hours

  @wash_orders = wash_orders_query.where(created_at: start_time..end_time).order(created_at: :asc)

  respond_to do |format|
    format.html
    format.csv { send_data to_csv(@wash_orders), filename: "WO-#{Time.now.strftime('%y%m%d')}.csv" }
  end
end

验证方式

  1. 在页面选择自定义日期范围,确认页面数据更新;
  2. 点击导出CSV链接,检查导出文件内容是否与页面显示一致。

内容的提问来源于stack exchange,提问作者fernandozuniga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:43:25