1

У меня есть приложение для рельсов с двумя моделями: расписание и задача. Задача принадлежит_описанию и расписанию has_many Задачи. Я использую вложенную форму с javascript, чтобы позволить пользователю вводить столько задач, сколько они хотят при создании расписания. Вот моя форма:набор динамических вложенных имен форм и идентификационных атрибутов

<%= form_for [@project, @schedule] do |f| %> 
    <%= f.fields_for :tasks do |builder| %> 
     <%= render 'task_fields', :f => builder %> 
    <% end %> 
    <p><%= link_to_add_fields "Add task", f, :tasks %> 
    <p><%= f.submit "Submit" %></p> 
<% end %> 

А вот парциальное форму выше относится к:

<p class = "fieldo"> 

    <%= f.label :title %><br /> 
    <%= f.text_field :title %><br /> 

    <%= f.label :content %><br /> 
    <%= f.text_field :content %><br /> 

    <%= f.hidden_field :_destroy %> 

    <%= link_to_function "remove", "remove_fields(this)" %> 
</p> 

Здесь действие расписания контроллер для формы:

def new 
    2.times {@schedule.tasks.build} 
end 

Так что, как вы можете видеть из контроллера, форма автоматически распечатает 2 формы задачи на странице. Эти 3 формы дают следующий HTML:

<p class = "fieldo"> 
    <input id="schedule_tasks_attributes_0_title" name="schedule[tasks_attributes][0][title]" type="text" /><br /> 
    <input id="schedule_tasks_attributes_0_content" name="schedule[tasks_attributes][0][content]" type="text" /><br /> 
</p> 
<p class = "fieldo"> 
    <input id="schedule_tasks_attributes_1_title" name="schedule[tasks_attributes][1][title]" type="text" /><br /> 
    <input id="schedule_tasks_attributes_1_content" name="schedule[tasks_attributes][1][content]" type="text" /><br /> 
</p> 

Как вы можете видеть, идентификатор и имя начинается с 0 и увеличивается на 1. Это хорошо и то, как я бы ожидать, что она работает. Проблема заключается в том, что, когда я добавить задачу динамически, нажав на кнопку «Добавить задачу», идентификатор и имя становятся случайными числами, как это:

<p class = "fieldo"> 
    <input id="schedule_tasks_attributes_1387479041550_title" name="schedule[tasks_attributes][1387479041550][title]" type="text"> 
    <input id="schedule_tasks_attributes_1387479041550_content" name="schedule[tasks_attributes][1387479041550][content]" type="text"> 
</p> 
<p class = "fieldo"> 
    <input id="schedule_tasks_attributes_1387479043642_title" name="schedule[tasks_attributes][1387479043642][title]" type="text"> 
    <input id="schedule_tasks_attributes_1387479043642_content" name="schedule[tasks_attributes][1387479043642][content]" type="text"> 
</p> 

Мои вопросы:

  1. Каковы эти цифры и как они генерируются?
  2. Есть ли способ изменить это, чтобы получить более аккуратные номера, не нарушая функциональность?

Если кто-либо видел рельсы, отличные # 197, эта форма немного основана на этом. Вот мой javascript и рубиновый помощник, которым я тоже пользуюсь.

JavaScript:

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

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

} 

помощник Применение:

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| 
     render(association.to_s.singularize + "_fields", :f => builder) 
    end 
    link_to_function(name, raw("add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")")) 
end 

ответ

0

1): Это огромное количество исходит из строки Javascript var new_id = new Date().getTime();, которая устанавливает идентификатор HTML новой строки с меткой времени, что делает ее «почти» uniq.


2): Да, вы можете изменить это, чтобы использовать «разумный человеческий номер».

function add_fields(link, association, content) { 
     var new_id = Math.floor((Math.random()*10000)+3); 
     var regexp = new RegExp("new_" + association, "g"); 
     $(link).parent().before(content.replace(regexp, new_id)); 
} 

Это заменит огромное число случайным числом между 10003 и 3.Но я рекомендую вам разрешить Rails справиться с этим огромным числом: во-первых, это препятствует потенциальным злым пользователям вашего приложения, а во-вторых, это почти наверняка uniq id.


Но эй, всегда помните, # 1 Developper в правило:

Если он не сломался, не исправить.

+0

большое спасибо! – Philip7899

+0

Не может ли приращение на 1 так же легко сделать их уникальными значениями? Если он работает для задач, встроенных в контроллер, почему это будет плохо для задач, созданных на сайте? – Philip7899

+0

Поскольку для временного поиска требуется меньше времени/строк кода, чем для сканирования входов, получить их идентификаторы html в виде строк, сканировать строки, чтобы найти индекс внутри, определить, какой из них самый большой, а затем увеличивать. Кроме того, это будет означать, что вычисление зависит от наличия других входов, которые добавляют еще одно ограничение. -> он становится менее гибким! – MrYoshiji

0

Не видя больше кода, трудно быть уверенным, но я думаю, что эти «временные» идентификаторы создается при task.build на стороне рельсов. Используйте debugger, pry, или некоторые puts @schedule.tasks.all.collect{|t| t.id}, чтобы проверить это.

Если это так, то нет, вы не можете «получить более аккуратные номера», но вы не захотите - вам просто нужны, чтобы они были уникальными, и для Rails прекрасно справлялись с созданием задач. Итак, просто проверьте, есть ли в вашей базе данных то, что вы ожидаете после действия create, и сделайте это.

Смежные вопросы