为浅路由调整 Rails 中的表格
Adjusting forms in Rails for shallow routing
我有模型的学生和清单,每个学生都有很多清单。我一直在尝试更改默认脚手架以使用浅层路由。我通过控制器根据操作设置清单和学生来修复,这似乎有效。但是我在 _form
部分遇到了问题,因为我不知道要更改什么 - 虽然我可以在嵌套路由的表单上找到内容,但对于浅层路由没有这样的帮助。
<%= form_with(model: [@student, checklist]) do |form| %>
<% if checklist.errors.any? %>
<div style="color: red">
<h2><%= pluralize(checklist.errors.count, "error") %> prohibited this checklist from being saved:</h2>
<ul>
<% checklist.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :title, style: "display: block" %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :date, style: "display: block" %>
<%= form.date_field :date %>
</div>
<div>
<%= form.label :setting, style: "display: block" %>
<%= form.text_field :setting %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
您真的不需要做很多事情就可以让表单与嵌套路由一起工作。
当您使用 form_with
时,它会将参数传递给 polymorphic route helpers,这将在尝试找到相应的路线时压缩数组:
# method | path
form_with(model: [Foo.find(1), Bar.new]) # POST | foo_bars_path(foo_id: 1)
form_with(model: [nil, Bar.new]) # POST | bars_path
form_with(model: [Foo.find(1), Bar.find(2)]) -> # PATCH | foo_bars_path(foo_id: 1, id: 2)
form_with(model: [nil, Bar.find(1)]) -> # PATCH | bar_path(1)
数组的最后一个元素被视为由表单生成器包装的实际对象。在处理浅嵌套时,您只需确保在更新记录时不传递父记录。
您可以通过在局部中使用一个“本地”来做到这一点:
<%= form_with(model: model) %>
# new.html.erb
<%= render partial: 'form', model: [@student, @checklist] %>
# edit.html.erb
<%= render partial: 'form', model: @checklist %>
或者您可以使用 local_assigns
散列来访问本地而不会在没有传递本地时引发 NoMethodError:
<%= form_with(model: [local_assigns[:student], checklist]) %>
# new.html.erb
<%= render partial: 'form', student: @student, checklist: @checklist %>
# edit.html.erb
<%= render partial: 'form', checklist: @checklist %>
这是可行的,因为局部变量不是实际的局部变量 - 相反,传递的局部变量存储在散列中并且Rails通过元编程动态提供访问器。
我有模型的学生和清单,每个学生都有很多清单。我一直在尝试更改默认脚手架以使用浅层路由。我通过控制器根据操作设置清单和学生来修复,这似乎有效。但是我在 _form
部分遇到了问题,因为我不知道要更改什么 - 虽然我可以在嵌套路由的表单上找到内容,但对于浅层路由没有这样的帮助。
<%= form_with(model: [@student, checklist]) do |form| %>
<% if checklist.errors.any? %>
<div style="color: red">
<h2><%= pluralize(checklist.errors.count, "error") %> prohibited this checklist from being saved:</h2>
<ul>
<% checklist.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :title, style: "display: block" %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :date, style: "display: block" %>
<%= form.date_field :date %>
</div>
<div>
<%= form.label :setting, style: "display: block" %>
<%= form.text_field :setting %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
您真的不需要做很多事情就可以让表单与嵌套路由一起工作。
当您使用 form_with
时,它会将参数传递给 polymorphic route helpers,这将在尝试找到相应的路线时压缩数组:
# method | path
form_with(model: [Foo.find(1), Bar.new]) # POST | foo_bars_path(foo_id: 1)
form_with(model: [nil, Bar.new]) # POST | bars_path
form_with(model: [Foo.find(1), Bar.find(2)]) -> # PATCH | foo_bars_path(foo_id: 1, id: 2)
form_with(model: [nil, Bar.find(1)]) -> # PATCH | bar_path(1)
数组的最后一个元素被视为由表单生成器包装的实际对象。在处理浅嵌套时,您只需确保在更新记录时不传递父记录。
您可以通过在局部中使用一个“本地”来做到这一点:
<%= form_with(model: model) %>
# new.html.erb
<%= render partial: 'form', model: [@student, @checklist] %>
# edit.html.erb
<%= render partial: 'form', model: @checklist %>
或者您可以使用 local_assigns
散列来访问本地而不会在没有传递本地时引发 NoMethodError:
<%= form_with(model: [local_assigns[:student], checklist]) %>
# new.html.erb
<%= render partial: 'form', student: @student, checklist: @checklist %>
# edit.html.erb
<%= render partial: 'form', checklist: @checklist %>
这是可行的,因为局部变量不是实际的局部变量 - 相反,传递的局部变量存储在散列中并且Rails通过元编程动态提供访问器。