与创建父级同时创建多个子级

时间:2019-07-12 00:34:18

标签: ruby-on-rails

出于学习目的,我正在开发一个简单的Rails任务列表应用程序,我希望在该应用程序上拥有的一件事就是能够在创建新列表的同时添加该列表中的任务。我已经完成了用于创建列表的基本CRUD操作,现在我想添加与创建列表同时创建任务的功能。

我已经完成了一些类似的初始关联:

我的列表模型:

class List < ApplicationRecord
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

我的任务模型:

class Task < ApplicationRecord
  belongs_to :list
end

我还更改了list_params以也返回任务:

def list_params
  params.require(:list).permit(:title, :public, task_attributes: [:text])
end

现在我的问题是如何为我的列表编写表格,并可以在其中添加动态数量的任务,然后将这些任务发送到我的create操作中以进行保存。

我的new操作非常简单:

def new
  @list = List.new
end

我当前的表单如下:

<%= form_with scope: :list, url: lists_path, local: true do |form| %>
  <p>
    <%= form.label :title %><br>
    <%= form.text_field :title %>
  </p>
  <p>
    <%= form.label :public %><br>
    <%= form.check_box :public %>
  </p>
  <h2>Tasks</h2>
  <%= form.fields_for :tasks do |task_form| %>
    <p>
    <%= task_form.label :text %><br>
    <%= task_form.text_field :text %><br>
    </p>
  <% end %>
  <p>
    <%= form.submit %>
  </p>
<% end %>

我打算将其用于测试目的,首先创建一个包含一个任务的列表,然后创建包含两个任务的列表,最后创建一些代码,以便能够通过javascript添加新字段,因此我可以创建无限多个任务。但是,我遇到的问题是,当我提交此表单并在params操作中调用create时,我可以看到它包含我的任务:

参数

{\"utf8\"=>\"✓\", \"authenticity_token\"=>\"...\", \"list\"=>{\"title\"=>\"list\", \"public\"=>\"0\", \"tasks\"=>{\"text\"=>\"task\"}}, \"commit\"=>\"Save List\", \"controller\"=>\"lists\", \"action\"=>\"create\"}"

但是当我尝试查看list_params中包含的内容时,却忽略了任务:

list_params

{\"title\"=>\"list\", \"public\"=>\"0\"}"

此外,如果我在任务表单中添加两个文本字段,例如用“ task1”和“ task2”填充,则在params中得到的只是“ task2”,似乎覆盖了先前的任务

所以我的问题是

1)我是否正确填写表格?我应该如何更改它以便允许多个任务?

2)为什么我的list_params不返回任务中的任何数据?

我想作为一个奖励,是否还有其他事情要我能够在任务执行的同时保存列表?

编辑:如果有人想尝试一下,这是我项目的github链接:https://github.com/bpromas/task-list

2 个答案:

答案 0 :(得分:1)

也许这可以帮助您。

看看这个宝石:https://github.com/nathanvda/cocoon

答案 1 :(得分:0)

我创建了一个新的Rails应用,并尝试遵循您提供的代码。

rails new a
rails generate scaffold List title public:boolean
rails generate scaffold Task text list:references
rails db:migrate

然后我像您一样编辑了模型

app / models / list.rb

class List < ApplicationRecord
  has_many :tasks
  accepts_nested_attributes_for :tasks
end

app / models / task.rb

class Task < ApplicationRecord
  belongs_to :list
end

现在,我查看了您的代码,但我不明白您如何初始化要在form.fields_for中显示的任务。我将打印出我知道的两种可能性。

第一种可能性是在_form.html.erb中创建Task的新实例

<%= form.fields_for :tasks, Task.new do |task_form| %>
   <p>
      <%= task_form.label :text %><br>
      <%= task_form.text_field :text %>
   </p>
<% end %>

第二种可能性是在list_controller.rb中构建Task的新实例

def new
  @list = List.new
  @list.tasks.build
end

我的list_params方法相同

def list_params
  params.require(:list).permit(:title, :public, tasks_attributes: [:text])
end

对于我来说,通过上述所有步骤,该应用程序均能正常运行,并为相应列表保存了任务。检查控制台是否显示红色消息,例如“ Unpermitted parameter::tasks_attributes”,如果是,则需要查看一些缺少的步骤。

完成这项工作然后更改代码以显示更多任务字段的时间很容易,只需在_form.html.erb中传递一个新Task数组或在lists_controller.rb中创建更多构建版本即可。

第一种选择

<%= form.fields_for :tasks, [Task.new, Task.new] do |task_form| %>
   <p>
      <%= task_form.label :text %><br>
      <%= task_form.text_field :text %>
   </p>
<% end %>

第二种选择

def new
  @list = List.new
  2.times { @list.tasks.build }
end

祝你好运!