如何在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
相关产品推荐
相关产品推荐

