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

如何在Rails控制器create动作中为子记录合并字段到强参数?

在Rails 7控制器中为嵌套的Person记录添加account_id

你可以在控制器的create方法中,手动为嵌套的people_attributes注入account_id,避免模型依赖父记录的关联。核心思路是处理参数时,给每个新建的Person记录(没有id属性的条目)添加当前账户的ID,具体实现如下:

class ClientsController < ApplicationController

  def new
    @client = Client.new
    @client.people.build
  end

  def create
    # 深拷贝参数避免修改原始params对象
    processed_params = client_params.deep_dup
    
    # 遍历嵌套的people属性,注入account_id
    if processed_params[:people_attributes].present?
      processed_params[:people_attributes].each do |_, person_attrs|
        # 仅为新建的Person添加account_id(已有id的是编辑的旧记录)
        person_attrs[:account_id] = current_account.id unless person_attrs[:id].present?
      end
    end

    @client = current_account.clients.build(processed_params.merge(creator_id: current_user.id))
    if @client.save
      flash[:notice] = "Client created."
      redirect_to edit_client_url(@client)
    else
      @client.people.build unless @client.people.any?
      render :new
    end
  end

private

  def client_params
    safe_attributes = [
      :name,
      people_attributes: Person::ATTRIBUTES + [:id, :_destroy]
    ]
    params.require(:client).permit(*safe_attributes)
  end

end

关键说明:

  • 使用deep_dup复制参数:因为Rails的params对象是不可变的,深拷贝后才能安全修改嵌套属性。
  • 只处理新建记录:通过判断person_attrs[:id]是否存在,避免覆盖已有Person记录的account_id。
  • 保持模型纯净:模型无需感知client.account的关联,所有上下文相关的属性注入都在控制器完成,符合关注点分离原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:05:46