1。和 2. - 将表单助手绑定到模型实例
除了在 2. 中您从实例变量引用模型实例而不只是传递方法调用的返回值这一事实之外,基本相同。
最终结果是您获得了一个绑定到模型实例的表单。这意味着输入的值属性将包含来自模型的值。
事实上,所有这些都会给出相同的结果:
<%
@pack = Pack.find(params[:id])
pack = Pack.find(params[:id])
%>
<%= simple_form_for Pack.find(params[:id]), method: :patch do |f| %>
<%= simple_form_for @pack |f| %>
<%= simple_form_for pack |f| %>
但第一个不太理想,因为您应该避免直接从视图中进行查询。视图应该从控制器接收数据并使用它来创建 HTML 并尽可能简单和声明性。另一个主要问题是.find 会引发ActiveRecord::RecordNotFoundError,如果 id 无效,它应该在控制器中更早地被捕获。
3。用符号调用表单助手:
<%= simple_form_for :pack, url: pack_path(@pack), method: :patch do |f| %>
这会创建一个“范围”的表单,而不必绑定到特定的模型实例。举个例子:
<%= simple_form_for :thing do |f| %>
<%= f.input :name %>
<% end %>
这会生成以下 HTML:
<form novalidate="novalidate" class="simple_form thing" action="/things/new" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓" /><input type="hidden" name="authenticity_token" value="F4r1gLuboZc1CKIdn9qac0sefxSVIvkjxk9KsD+sRl1wnVtEIKzHvWY0mPuLPvHI1Kcv3TIWD883YXHKXA+yJQ==" />
<div class="input string required thing_name">
<label class="string required" for="thing_name"><abbr title="required">*</abbr> Name</label>
<input class="string required" type="text" name="thing[name]" id="thing_name" />
</div>
</form>
注意name="thing[name]" 这意味着它会给出一个参数哈希,就像我们有一个模型实例一样:
{
thing: {
name: "foo"
}
}
这并不常用(至少不正确),因为大多数时候您都在操作模型实例,但它在搜索表单等特殊情况下确实有用。
请注意,Rails 将尝试解析局部变量 @thing,但如果它为 nil,则不会引发错误。因此,通常不建议使用此表单,因为它会掩盖错误。
了解这种行为的最佳方式是阅读 ActionView::FormHelpers 的文档,SimpleForm 只是其中的糖。