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

当Grn参数rejected_qty存在时,如何在其控制器create方法创建Pms::Srn嵌套记录

如何在GRN创建后自动生成带嵌套模型的SRN记录?

问题场景

我现在有一个Pms::GrnsController(继承自Pms::PmsModulesController),在create方法里成功保存Pms::Grn实例后,如果params[:pms_grn][:rejected_qty]存在,需要创建包含嵌套模型的Pms::Srn记录。现有代码框架如下:

控制器代码:

class Pms::GrnsController < Pms::PmsModulesController
  def create
    @pms_grn = Pms::Grn.new(pms_grn_params)
    respond_to do |format|
      if @pms_grn.save
        if params[:pms_grn][:rejected_qty].present?
          @pms_srn = Pms::Srn.create()# 此处需创建包含嵌套模型的pms_srn记录
        end
      end
    end
  end
end

模型代码:

class Pms::Srn < ActiveRecord::Base
  ...
end

实现方案

要搞定这个需求,我们需要从模型配置、参数处理、控制器逻辑三个方面入手:

1. 给Srn模型配置嵌套属性支持

首先得确保Pms::Srn能处理嵌套模型,假设你的嵌套模型是Pms::SrnItem(换成你实际的嵌套模型名就行),在Srn模型里添加关联和嵌套属性声明:

class Pms::Srn < ActiveRecord::Base
  # 关联嵌套模型,dependent: :destroy可选,根据业务需求决定
  has_many :srn_items, class_name: 'Pms::SrnItem', dependent: :destroy
  # 允许嵌套属性,allow_destroy: true支持删除嵌套记录,按需开启
  accepts_nested_attributes_for :srn_items, allow_destroy: true

  # 别忘了加上和Grn的关联
  belongs_to :grn, class_name: 'Pms::Grn'

  # 其他原有代码...
end

2. 调整控制器的参数白名单

在pms_grn_params里,需要允许rejected_qty以及嵌套模型的参数,不然Rails会把这些参数过滤掉:

private

def pms_grn_params
  params.require(:pms_grn).permit(
    # 这里放Grn本身需要的字段,比如vendor_id、grn_date之类的,替换成你的实际字段
    :vendor_id, :grn_date,
    :rejected_qty,
    # 嵌套模型的参数,字段名根据你的SrnItem模型调整
    srn_items_attributes: [:id, :product_id, :qty, :_destroy]
  )
end

3. 完善create方法里的Srn创建逻辑

现在可以在Grn保存成功后,构建完整的参数来创建带嵌套模型的Srn了:

def create
  @pms_grn = Pms::Grn.new(pms_grn_params)
  respond_to do |format|
    if @pms_grn.save
      if params[:pms_grn][:rejected_qty].present?
        # 构建Srn的基础参数,关联刚创建的Grn,传递拒绝数量
        srn_attributes = {
          grn_id: @pms_grn.id,
          rejected_qty: params[:pms_grn][:rejected_qty],
          # 可以加上其他必填字段,比如创建人、创建时间之类的
          created_by: current_user&.id # 假设你用devise之类的有current_user
        }

        # 如果前端提交了嵌套模型的参数,添加到Srn的参数里
        if params[:pms_grn][:srn_items_attributes].present?
          srn_attributes[:srn_items_attributes] = params[:pms_grn][:srn_items_attributes]
        end

        # 创建Srn记录
        @pms_srn = Pms::Srn.create(srn_attributes)

        # 给用户反馈创建结果
        if @pms_srn.persisted?
          format.html { redirect_to pms_grn_path(@pms_grn), notice: 'GRN保存成功,SRN已生成。' }
        else
          format.html { redirect_to pms_grn_path(@pms_grn), alert: "GRN保存成功,但SRN生成失败:#{@pms_srn.errors.full_messages.join(', ')}" }
        end
      else
        format.html { redirect_to pms_grn_path(@pms_grn), notice: 'GRN保存成功。' }
      end
    else
      format.html { render :new }
    end
  end
end

几个要注意的点

  • 嵌套参数格式:如果是表单提交,前端的嵌套参数要符合Rails的格式,比如srn_items_attributes[0][product_id],这样Rails才能正确解析成数组。
  • 关联完整性:确保Pms::Grn模型里也有对应的关联(比如has_one :srn, class_name: 'Pms::Srn'),这样后续查询关联数据更方便。
  • 事务处理:如果GRN和SRN需要保证原子性(要么都创建成功,要么都失败),可以把整个逻辑包在事务里:
    ActiveRecord::Base.transaction do
      @pms_grn.save!
      # 创建SRN的代码
      @pms_srn.save!
    end
    
    这样如果任何一步失败,都会回滚之前的操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:21:35