当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
相关产品推荐
相关产品推荐

