我有一个rails 4应用程序,其形式如下:
<%= form_for @store, :html => {:multipart => true} do |f| %>
<%= f.fields_for :products do |product| %>
<%= render partial: "edit_product_fields", locals: {product:product} %>
<% end %>
<%= f.submit %>
<% end %>
和edit_product_fields部分看起来像:
<select>
<option value="Textbook" <% if product.type_of == "Textbook" %>selected<% end %>>Textbook</option>
<option value="Magazine" <% if product.type_of == "Magazine" %>selected<% end %>>Magazine</option>
<option value="Book" <% if product.type_of == "Book" %>selected<% end %>>Book</option>
</select>
当我有这样的代码时,我收到错误:
undefined method `type_of' for #<NestedForm::Builder:0x00000102304f78>
但如果我将渲染线更改为(我只是通过取出 partial:使其不那么明确):
<%= render "edit_product_fields", locals: {product:product} %>
我收到错误:
undefined local variable or method `product' for #<#<Class:0x0000010235a248>:0x0000010684b3c0>
答案 0 :(得分:2)
在您的第一个代码块中,您将Builder
对象存储为product
。
幸运的是,Builder
提供了object
方法,因此您可以访问它在表单中表示的实际对象:
<select>
<option value="Textbook" <%= 'selected' if product.object.type_of == "Textbook" %>>Textbook</option>
<option value="Magazine" <%= 'selected' if product.object.type_of == "Magazine" %>>Magazine</option>
<option value="Book" <%= 'selected' if product.object.type_of == "Book" %>>Book</option>
</select>
答案 1 :(得分:2)
好type_of
不是ruby方法。它看起来像是尝试键入检查...但是类型检查通常不会被鸭子类型的语言所禁止。无论如何,我们可以利用Rails Form Helper来代替这个代码。但首先......
更改后render
抱怨undefined local variable or method
product'的原因是因为渲染调用要求第一个参数是部分名称,第二个参数是本地的哈希值:
<%= render "partial_name", local1: "a", local2: "b" %>
...或者它希望整个事情都是哈希:
<%= render partial: "partial_name", locals: { local1: "a", local2: "b" } %>
现在,回到表单助手。
您在这里寻找的是select帮手。这使得以下成为可能:
<%= product.select :type_of, %w[Textbook Magazine Book] %>
这将呈现与您放入_edit_product_field.html.erb
部分相同的html。因此,您可能只需要删除部分以节省渲染时间并将其直接放入表单中。
另一个,小问题。调用fields_for
块变量product_form
而不是product
可能不那么令人困惑。这是为了帮助记住,这不是您正在处理的Product对象,而是Form Generator对象。此外,您不需要在Rails 4表单中指定:multipart => true
- 如果您在表单正文中有文件上传元素,则Rails知道如何使表单成为多部分。
所以把它们放在一起:
<%= form_for @store do |f| %>
<%= f.fields_for :products do |product_form| %>
<%= product_form.select :product, %w[Textbook Magazine Book] %>
<% end %>
<%= f.submit %>
<% end %>