简体   繁体   English

Rails嵌套属性form_for for has_many,使用javascript无限制嵌套模型

[英]Rails Nested Attributes form_for for has_many with unlimited nested models using javascript

So I've got a pretty simple model with nested attributes set up: 所以我有一个非常简单的模型,其中设置了嵌套属性:

class Property < ActiveRecord::Base
  has_many :trees
  accepts_nested_attributes for :trees
end

Then I build them in my controller: 然后我在我的控制器中构建它们:

class PropertiesController < ApplicationController

  def new
    @property = Properties.new
    @trees = @property.trees.build
  end
end

And then in my view (using slim): 然后在我看来(使用苗条):

= form_for @property |p|
  = p.text_field :name

  .tree
    = p.fields_for :trees do |t|
      = t.text_field :fruit
      = t.select :quantity, (1..1000).to_a

    = link_to 'Add Another Tree', new_properties_path, id: 'new-tree'

And then in my js (coffeescript) file, bound to the click event of the '#new-tree' anchor: 然后在我的js(coffeescript)文件中,绑定到'#new-tree'锚点的click事件:

event.preventDefault()
tree = $(event.target).parents('.tree')
tree.after tree.clone(true)

This works as you would expect, however when I submit the form, only the last tree params get submitted. 这可以按照您的预期工作,但是当我提交表单时,只提交最后一个树参数。 This is because in the generated html of the form_for I get something like this: 这是因为在form_for的生成的html中我得到这样的东西:

<input type="text" id="property_trees_attributes_0_fruit" name="property[trees_attributes][0][fruit]">
<select id="property_trees_attributes_0_quantity" name="property[trees_attributes][0][quantity]" class="valid">
  <option value="1">1</option>
  <option value="2">2</option>
  <option value="3">3</option>
  ...
</select>

And when I clone this html I get the name and id with the 0 in it, though I believe it should be a 1 to add additional tree params, etc. 当我克隆这个html时,我得到了名字和id,其中包含0 ,但我相信它应该是1来添加额外的树参数等。

I tried to compensate with the js by doing something like this: 我试图通过做这样的事来补偿js:

event.preventDefault()
tree = $(event.target).parents('.tree')
clone = tree.clone()
number = parseInt(clone.find('input[type=text]').attr('id').match /[0-9]/)
next = number + 1
clone = clone.html().replace /_(#{number})_|\[(#{number})\]/, next
section.after clone

The point of the regex is to replace any numbers between two underscores or two brackets, like _0_ or [0] 正则表达式的要点是替换两个下划线或两个括号之间的任何数字,如_0_[0]

My regex doesn't seem to work though. 我的正则表达式似乎不起作用。 It replaces _0_ with just 1 and this solution seems messy to me anyways. 它只用1替换_0_ ,这个解决方案对我来说似乎很麻烦。 I would make the regex simpler, however then I have to worry about it changing the value of the select menu options. 我会使正则表达式更简单,但是我不得不担心它会改变选择菜单选项的值。

Any suggestions for cleaning this up? 有关清理的建议吗? Am I missing something really obvious? 我错过了一些非常明显的东西吗

The problem you have is you're just duplicating DOM elements - this is IMO a hack, as you're not building the objects you need before-hand (won't persist the data etc) 你遇到的问题是你只是复制了DOM元素 - 这是IMO的一个黑客攻击,因为你没有先构建你需要的对象(不会持久保存数据等)

We've implemented an "add extra fields to f.fields_for " using Ajax before - there's a great tutorial here and a RailsCast here 我们之前使用Ajax实现了“向f.fields_for添加额外字段” - 这里有一个很棒的教程,这里有一个RailsCast


child_index CHILD_INDEX

The answer to your question is to use the child_index option in the fields_for helper, and to make that use an integer timestamp: 您的问题的答案是使用fields_for帮助程序中的child_index选项,并使用integer时间戳:

<% index = Time.now.to_i %>
<%= f.fields_for :trees, child_index: index do |fields| %>
    #your fields here
<% end %>

Code

Here's what we do: 这就是我们的工作:

#app/views/properties/new.html.erb
<%= form_for @property do |f| %>
   <%= render partial: "trees_fields", locals: { f: f, child_index: Time.now.to_i } %>
   <%= link_to "New Field", new_field_property_path %>
<% end %>

#app/views/properties/_trees_fields.html.erb
<%= f.fields_for :trees, child_index: child_index do |trees| %>
   <%= trees.text_field :your_attr %>
<% end %>

#app/controllers/properties_controller.rb
def new_field
    @property = Property.new
    @property.trees.build
    render "add_tree", layout: false
end

#app/views/properties/add_tree.html.erb
<%= form_for @property do |f| %>
      <%= render partial: "trees_fields", locals: {f: f, child_index: Time.now.to_i} %>
<% end %>

 #app/assets/javascripts/application.js.coffee
$ ->
  $(document).on "click", "#add_tree", (e) ->
     e.preventDefault();
     $.ajax
       url: '/messages/add_subscriber'
       success: (data) ->
              el_to_add = $(data).html()
          $('#trees_form').append(el_to_add)
       error: (data) ->
          alert "Sorry, There Was An Error!"

You are right, nested .tree elements shouldn't have the same id. 你是对的,嵌套的.tree元素不应该有相同的id。 So you shouldn't clone them. 所以你不应该克隆它们。 Instead build new item using helper, generate id based on current time for instance and then paste new nested element. 而是使用帮助器构建新项目,例如,基于当前时间生成id,然后粘贴新的嵌套元素。 This is a complex scenario, so I think it would be better to watch related railscasts: 这是一个复杂的场景,所以我认为观看相关的railscast会更好:

  1. http://railscasts.com/episodes/196-nested-model-form-part-1 http://railscasts.com/episodes/196-nested-model-form-part-1
  2. http://railscasts.com/episodes/197-nested-model-form-part-2 http://railscasts.com/episodes/197-nested-model-form-part-2
  3. http://railscasts.com/episodes/196-nested-model-form-revised http://railscasts.com/episodes/196-nested-model-form-revised

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Rails 6 使用 has_many 关系和 accepts_nested_attributes_for 连接表 - Rails 6 Joins Tables using has_many relationships and accepts_nested_attributes_for Rails通过连接记录通过JavaScript将新的has_many附加到嵌套表单 - Rails append new has_many through join record to nested form via javascript Rails form_for has_many通过使用AJAX的关联不起作用 - Rails form_for has_many through association using AJAX not working has_many和accepts_nested_attributes_for具有嵌套表单和jquery / ajax - has_many and accepts_nested_attributes_for with nested forms and jquery/ajax Nested_form_fields在验证失败时显示现有的has_many嵌套字段 - Nested_form_fields show existing has_many nested fields upon validation failure 如何在没有nested_form的情况下将表单写入has_many关联? - How to write form to has_many association without nested_form? (Ruby,Rails,Javascript)使用JavaScript窗口等管理嵌套模型吗? - (Ruby, Rails, Javascript) Managing nested models using javascript windows, etc…? Javascript无限嵌套数组处理 - Javascript unlimited nested array handling 带有Java语言的Rails 3嵌套模型表单 - Rails 3 Nested Model Form with Javascript Rails嵌套属性javascript添加另一个 - Rails nested attributes javascript add another
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM