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

Rails 5结合dry-monads的预约批量创建接口代码优化问询

优化方案

核心思路是利用Ruby内置迭代方法避免手动声明临时变量,同时复用dry-monads的返回结构减少冗余存储,优化后代码如下:

class Api::AppointmentsController < ApplicationController
  def create
    # 单次遍历拆分成功/失败结果,无需提前声明空数组
    result = batch_create_appointments_params[:_json].each_with_object({ success: [], failure: [] }) do |appointment_params, res|
      appointment = ::Appointments::Create.new(appointment_params).call
      # 可选:用dry-monads内置的either方法替代if判断,更贴合函数式范式
      appointment.either(
        ->(success_appo) { res[:success] << success_appo },
        ->(failure_info) { res[:failure] << failure_info }
      )
    end

    if result[:failure].any?
      # 直接从失败结果中提取错误,无需单独维护错误数组
      errors = result[:failure].flat_map { _1[:appointments_errors] }
      AppointmentMailer.failed_mail(email, result[:failure].size, errors).deliver_now
      render json: { error: errors.join(', ') }, status: :bad_request
    else
      AppointmentMailer.success_mail(email, result[:success].size).deliver_now
      render json: {
        success: result[:success].as_json(include: %i[car customer work_orders])
      }
    end
  end
end

如果不习惯either写法,也可以保留原有的success?判断逻辑,仅替换迭代部分即可:

result = batch_create_appointments_params[:_json].each_with_object({ success: [], failure: [] }) do |appointment_params, res|
  appointment = ::Appointments::Create.new(appointment_params).call
  if appointment.success?
    res[:success] << appointment.value!
  else
    res[:failure] << appointment.failure
  end
end

优化说明

  • 去掉了三个预先声明的空数组,用each_with_object在单次遍历中直接构建结果集合,代码更紧凑
  • 复用dry-monads返回的Failure结构中的错误信息,不需要单独维护appointments_errors数组,减少冗余数据
  • 整体时间复杂度和原代码一致为O(n),无额外性能开销

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:06:03