Rails 5 在一个表单中创建同一个模型的多条记录,未知属性错误

Rails 5 Create Multiple Records of Same Model in One Form, Unknown Attribute Error

我需要制作一个可以处理同一模型的多个记录的创建的表单,并以通过 Rails' 强参数的方式提交信息。在前端,我为小狗名称和品种动态添加了两个新文本字段,并希望将它们全部保存到一个表单中。但是我无法通过 Strong Params 传递小狗名称和品种的数组;获得

unknown attribute ‘puppies’ for Puppy

我认为这是我忽略的非常简单的事情。请帮助生成这些小狗!

new.html.erb

<%= form_tag puppies_path do %>
 <%= text_field_tag “puppies[puppies][]puppy[name]” %>
 <%= text_field_tag “puppies[puppies][]puppy[breed]” %>
 <%= submit_tag “Add Puppy” %>
<% end %>

生成这些参数

"puppies"=>{"puppies"=>[{"puppy"=>{"name"=>"ribbon", "breed"=>"poodle"}}]}

和控制器中的强参数

class PuppiesController < ApplicationController
  def index
    @puppies = Puppy.all
  end

  def new
  end

  def create
    puppies_array = puppies_params[:puppies].each do |puppy|
                      puppy[:puppy]
                    end
    Puppy.create(puppies_array)
  end 

  def show
    @puppy = Puppy.find(params[:id])
  end  

  private
    def puppies_params
      params.require(:puppies).permit({ 
        puppies: [
          puppy: [
            :name, 
            :breed
          ] 
        ]
      })
    end  
end

知道我遗漏了什么吗?

我要通过的伪代码:

[(name, breed), (name, breed), (name, breed)]

怎样才能正确书写?我正在学习本教程 https://medium.com/@dmccoy/how-to-build-html-inputs-to-submit-an-array-of-hashes-with-a-rails-form-tag-that-work-with-strong-f70a6c03d78e

您还没有添加其余的控制器代码,但我假设您正在使用类似的代码:Puppy.create(puppies_params)

但是由于您在视图中嵌套了参数,因此您将需要使用 Puppy.create(puppies_params[:puppies]) 来确保您能够将正确的名称数组和品种传递到 create 操作中。

编辑 由于 puppies 数组包含一个带有 puppy 键的散列,我们需要提取它们以获得最终的 puppy 属性数组。

def create
  puppies_array = puppies_params[:puppies].collect do |puppy|
                    puppy[:puppy]
                  end
  Puppy.create(puppies_array)
end

我下面的评论中有一个 shorthand 用于设置 puppies 数组,您可以使用对您来说更易读和理解的版本

要获得所需的属性数组,您可以这样做:

puppies_array = puppies_params[:puppies][:puppy].map{|puppy| puppy.values}

这在 puppy 参数中获取散列 puppies,在 puppy 中获取散列数组,然后只获取该数组中散列的值部分。

你会得到你的伪代码结果。

有关信息,请注意地图块中的 puppy 没有特殊意义...它只是表示数组的实例。您可以轻松做到

puppies_array = puppies_params[:puppies][:puppy].map{|some_dog| some_dog.values}