Проблема с рендерингом вложенных форм

0

У меня есть приложение 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>

но если я изменю линию рендеринга (я просто сделал это менее явным, выбирая частичную :):

<%= render "edit_product_fields", locals: {product:product} %>

Я получаю сообщение об ошибке:

undefined local variable or method 'product' for #<#<Class:0x0000010235a248>:0x0000010684b3c0>
  • 1
    Интересно, насколько хорош этот драгоценный камень. в прошлый раз, когда я пытался использовать nested_form , он не работал для меня. Поэтому я выбрал cocoon жемчужина
  • 0
    @WaliAli Я не думаю, что ОП здесь ссылается на драгоценный камень, а просто на понятие вложенных атрибутов.
Показать ещё 1 комментарий
Теги:
forms

2 ответа

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>
  • 0
    Спасибо за ответ. Я попробовал это, но получил undefined method type_of for #<Class:0x000001064bcf60>
  • 0
    Как я уже говорил, попробуйте product.object.class.name или product.object.is_a? Textbook вместо type_of . Я даже не уверен, существует ли type_of в Ruby или Rails.
Показать ещё 3 комментария
2

Ну type_of не является рубиновым методом. Похоже, что это попытка набрать проверку, хотя... Но проверка типа обычно недоверчива на языках с утиным языком. Во всяком случае, мы можем использовать Reld Form Helper вместо этого и сделать этот код однострочным. Но сначала...

Причина, по которой render жалуется на undefined local variable or method продукт undefined local variable or method '' после вашего изменения, заключается в том, что вызов рендеринга ожидает, что первый аргумент будет частичным именем, а второй - хешем для локальных пользователей:

<%= render "partial_name", local1: "a", local2: "b" %>

... или он ожидает, что все это будет хешем:

<%= render partial: "partial_name", locals: { local1: "a", local2: "b" } %>

Теперь вернемся к помощнику формы.

То, что вы ищете, - это помощник выбора. Это делает возможным следующее:

<%= product.select :type_of, %w[Textbook Magazine Book] %>

И это будет отображать все те же html, что и в части вашего _edit_product_field.html.erb. Таким образом, вы, вероятно, должны просто избавиться от частичного, чтобы сохранить время рендеринга и поместить его прямо в вашу форму.

Еще один, второстепенный момент. Это может быть менее запутанным, чтобы вызывать fields_for переменной блока product_form вместо product. Это необходимо помнить, что это не объект Product, с которым вы имеете дело, а скорее объект Form Generator. Кроме того, вам не нужно указывать :multipart => true в Rails 4 form - 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 %>
  • 0
    Я должен был быть более ясным. type_of на самом деле поле в моей модели продукта. Я изменю свой вопрос, чтобы отразить это, извините.
  • 0
    Это лучший подход, но он должен быть <%= product_form.select :type_of, %w[Textbook Magazine Book] %> . Тогда я думаю, что у вас есть победитель!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню