Rails 嵌套表单 - 重构创建操作 |茧 gem

Rails nested form - refactor create action | cocoon gem

一切正常,但我想将 create 操作中的代码更改为 update 操作中的代码。现在,在创建操作中,我正在遍历所有值并保存它们,但我想在一行中完成。

我有一个学院模型。

class College< ActiveRecord::Base
   has_many :staffs, dependent: :destroy
   accepts_nested_attributes_for :staffs, reject_if: :all_blank, allow_destroy: true
end

这是我的 Staff.rb

class Staff < ActiveRecord::Base
  belongs_to :college
end

这些是我的 Staffs 控制器 createupdate actions

def create
  @college= College.find(params[:college][:id_college_profile]
  )
  staff_params = params[:college][:staffs_attributes].values
  staff_params.each do |staff_param|
    @staff = @college.staffs.new
    @staff.name = staff_param[:name]
    @staff.designation = staff_param[:designation]
    @staff.experience = staff_param[:experience]
    @staff.specialization = staff_param[:specialization]
    @staff.save
  end
  redirect_to dashboard_path(id: @college.id), notice: "Successfully added Staff."
end

def update
  @college= College.find(params[:college][:id_college]
  )
  @college.update_attributes(staff_parameters)
  redirect_to root_path
end

这些都是强参数

def staff_parameters
  params.require(:college).permit(:id, staffs_attributes: [:id,  :name, :specialization, :experience, :designation, :_destroy])
end

有没有办法在创建动作中保存所有员工,而不是循环遍历所有值,而是像更新动作一样用一行代码保存所有人员?

我已经在 StaffsController 创建操作中尝试过这个

def create
  @college= College.find(params[:college][:id_college]
  )
  @staff= @college.staffs.new(staff_parameters)
  @staff.save

  redirect_to dashboard_path(id: @college.id), notice: "Successfully added Staffs."
end

但是它抛出了这个错误

unknown attribute 'staffs_attributes' for Staff.

有人可以帮我解决这个问题吗?

您可以通过多种方式做到这一点。 "staff_parameters" 方法抛出错误,因为您在创建操作中对 class 员工调用它,在更新操作中对学院 class 调用它。做你想做的最简单的事情是复制人员参数方法强参数并复制它。将第二个方法命名为 create_staff,并将 "params.require(:college)" 部分更改为 "params.require(:staff)",其余部分保持不变。然后在您的创建操作中,您可以执行 "college.staff(create_staff)"。我在我的 phone 上所以格式不太好哈哈我把代码放在引号里。

这是 CollegesController 所以我假设 create 行动也创建了新学院?

所以在那种情况下,您的创建操作应该简单地类似于:

def create
  @college = College.new(staff_parameters)
  if @college.save
    # succesfully created
  else
    # there was a validation error
  end
end 

请注意,通常我们会使用 college_parameters,因为根元素是 college,并且您不仅可以编辑嵌套的员工,还可能编辑大学的属性。

如果大学总是已经存在(因为你正在做 find),我有点困惑 createupdate 之间的区别,为什么不呢在这种情况下总是呈现 edit 动作?

我有一个 demo-project 展示外壳茧和嵌套属性。