我认为我想要实现的目标非常简单。我希望有一个包含5个字段的表单,并且一个人可以从该表单创建任意数量的对象(即如果只填写1个字段,则创建1个对象,如果您填充2个字段,则创建2个对象等。 ..)
有趣的是,当我试图谷歌这个话题时,没有多少出现。我遇到的唯一“正当”例子是this。这导致我到达目前的位置(因为它不起作用)。
这是我的foo_controller.rb
def new
@foo = []
5.times do
@foo << Foo.new
end
end
def create
if params.has_key?("foos")
Foo.create(foo_params(params["foos"]))
else
params["foos"].each do |f|
Foo.create(foo_params(f))
end
end
end
private
def foo_params(my_params)
my_params.permit(:item_one, :item_two)
end
这是new.html.erb
<%= form_tag foos_path do %>
<% @foo.each do |f| %>
<% fields_for "foos[]", f do |ff| %>
#all the form stuff, labels, buttons etc
<% end %>
<% end %>
<% end %>
在我提交之前,我已经“知道”有一个问题。我的表单字段都具有相同的ID,这意味着即使“if”我可以毫无问题地提交,只有最后一个条目最终会访问数据库。所以......
问题#1 - 我如何拥有唯一的表格ID?
我面临的下一个问题是当我点击提交时,我收到此错误Rack::QueryParser::ParameterTypeError (expected Array (got Rack::QueryParser::Params)
,所以基本上params没有收到正确的内容。那是我的下一个问题......
问题2 - 传递一系列参数的正确方法是什么?
但这都假设THIS指南的解决方案有效。我几乎每走一步都走了,但空洞了。所以我想我的重大问题是:
如何创建单个模型的一个或多个对象?
答案 0 :(得分:2)
看起来你正朝着正确的方向前进。
如果要创建新记录,则不需要ID。如果您希望能够使用相同的表单编辑记录,那么生成ID可能会更好,但这更多地取决于您希望如何处理创建与更新。
这样做的方式是Rails查看表单元素的名称。如果名称中有空括号,Rails会将参数渲染为数组:
<input type="text" name="foo[bar][][baz]" value="one" />
<input type="text" name="foo[bar][][baz]" value="two" />
<input type="text" name="foo[bar][][baz]" value="three" />
params => { foo: { bar: ["one", "two", "three"]}}
但是,如果你有ID,Rails会将params渲染成哈希:
<input type="text" name="foo[bar][1][baz]" value="one" />
<input type="text" name="foo[bar][2][baz]" value="two" />
<input type="text" name="foo[bar][3][baz]" value="three" />
params => { foo: { bar: {1: "one", 2: "two", 3: "three"}}}
现在的诀窍是如何处理模型的创建。如果您想使用嵌套属性,可以通过设置#accepts_nested_attributes_for
并将所有内容嵌套在bar_attributes
下来实现。这将让你只需将params散列传递给模型,让它有一些魔力。
或者,您可能希望迭代params
哈希,并在控制器中创建每个模型。
或创建一个表单对象以包含所有逻辑。由你决定。
我将从手动迭代过度方法开始,让事情有效。然后你可以重构和清理。
在控制器中可能看起来像这样:
array_of_bars = foo_params[:bar].map do |bar_params|
Bar.new(baz: bar_params[:baz])
end
了解更多详情,请查看RailCast的Dynamic Forms和Nested Forms。在过去的几年里,我多次重复这些指南,并且每次都对结果代码感到满意。
答案 1 :(得分:0)
嵌套表单总是很棘手,但有些宝石可以帮到你。我最喜欢的一个是:https://github.com/nathanvda/cocoon
这是使用gem https://www.sitepoint.com/better-nested-attributes-in-rails-with-the-cocoon-gem/
的教程答案 2 :(得分:0)
我一直在处理相同的错误Rack :: QueryParser :: ParameterTypeError(期望的数组(得到Rack :: QueryParser :: Params)。This answer helped me to fix it.
错误是由具有ID的记录呈现为散列的事实引起的。解决方案:您不需要fields_for。删除fields_for块并仅使用表单标记帮助程序应该可以工作,例如:
text_field_tag "foos[][name]", f["name"]
通过这种方法,将不会有与您的参数混乱的ID。如果你提交并检查参数,你会看到一系列漂亮的哈希。