Динамическое добавление дочернего поля в форму, как описано в Railscast 197, не использует параметр: child_index для создания атрибута имени html - PullRequest
2 голосов
/ 24 сентября 2011

У меня есть приложение, в котором я пытаюсь добавить записи, как показано в Railscast № 197. Мои объекты более просты, так как у меня только один уровень отношений между родителями и детьми: пациенты и события.Код прекрасно работает для удаления дочерней записи (событий), но при добавлении записи происходит сбой по следующей причине.Я могу создать новый объект, сгенерировать поля для отображения на форме, и форма выглядит хорошо.Однако: child_index отсутствует в атрибуте name в сгенерированном html.Пример сгенерированного html:

<textarea cols="30" id="patient_events_attributes_description" name="patient[events_attributes][description]" rows="3"></textarea>

html существующей записи:

<textarea cols="30" id="patient_events_attributes_1_description" name="patient[events_attributes][1][description]"     rows="3">Opgepakt met gestolen goederen</textarea>

Обратите внимание, что [1] в существующей записи отсутствует в новом html,Конечно, это должен быть не 1, а new_xxx, который затем заменяется уникальным номером.Но весь [new_xxx] отсутствует в сгенерированном html.Кто-нибудь имеет представление о том, что не так?

Я использую Ruby 1.9.2, с Rails 3.0.10.У меня есть только JQuery без прототипа или query-ujs.

Код, который я использую, показан ниже, но он является копией кода Railscast:

    def link_to_remove_fields(name, f)
    f.hidden_field(:_destroy) + link_to_function(name, "remove_fields(this)")
  end

  def link_to_add_fields(name, f, association)
    new_object = f.object.class.reflect_on_association(association).klass.new
    fields = f.fields_for(association, new_object, :child_index => "new_#{association}") do |builder|      # new_#{association}
      render(association.to_s.singularize + "_fields", :f => builder)
    end
    link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")
  end

function remove_fields(link) {
    $(link).prev("input[type=hidden]").val = "1";
    $(link).closest(".fields").hide();
}

function add_fields(link, association, content) {
    alert(content);
  var new_id = new Date().getTime();
  var regexp = new RegExp("new_" + association, "g");
  $(link).before(content.replace(regexp, new_id));
}

Мне не удалось найти другие комментарии, связанные с этим кодом.не работает, поэтому я должен делать что-то очень неправильно.Есть идеи?

1 Ответ

1 голос
/ 25 сентября 2011

После просмотра исходного кода для fields_for я обнаружил две проблемы: 1. Параметр: child_index не используется, вместо этого используется опция: index. 2. fields_for генерирует правильный html, только если переданный объект является активным объектом записи или массивом. Я изменил параметр, переданный типу array, с новым пустым объектом в качестве записи [0].

Примечательно, что нет документации по этой функции. Использование ROR требует очень много времени, если вы там не родились.

Код, который наконец работает, выглядит следующим образом. Обратите внимание, что «99» необходимо заменить уникальным номером, если нужно добавить больше записей.

Я до сих пор не работал полностью, так как @ Patient.update_attributes (params [: пациент]) выдает некоторые ошибки, но худшая часть (добавление HTML) исправлена.

def link_to_add_fields(name, g, association)
new_object = []
new_object[0] = g.object.class.reflect_on_association(association).klass.new
fields = g.fields_for(association, new_object, :index => '99') do |builder|      # , {:child_index => "new_#{association}"} new_#{association}
  render(association.to_s.singularize + "_fields", :f => builder)
end
link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")

конец

...