Rails使用javascripting嵌套多态forms

我希望我的表格上有以下内容:

在此处输入图像描述

度是多态的部分,与profile的has_many关系。 这个部分由主要forms – 轮廓调用。 通过按“添加资格”,用户可以添加多个度数。 我已经能够只将一个学位附加到个人资料中,这是最后一个被忽略的人。 我甚至知道它为什么会发生,因为link_to无法传递配置文件实例。 所以我必须在degrees_controller中创建新的配置文件,你可以在我的代码中看到 。 提交“创建个人资料”时,最终个人资料实例是否可以选择上述所有其他个

请任何帮助,以便我可以将所有学位与表格相关联,我最后几天坚持使用SO和谷歌的所有排列和组合。 我已经准备好改变代码了……任何对此的帮助都将受到赞赏。

我有这个小帮手让我通过这些案件。 它可以重复使用,所以你不必在同一个应用程序中为不同的情况编写所有这些东西。

首先是代码:

module FormsHelper def data_for_field(f, subclass, options={}) new_object = f.object.class.new.send(subclass.to_s).new(options[:attributes]) id = new_object.object_id partial_path = options[:path] || new_object fields = f.fields_for(subclass, new_object, child_index: id) do |builder| render(partial_path, f: builder) end {id: id, fields: fields.gsub("\n", "")} end end 

一些JS魔术:

 $(document).on('click', '.add-fields', function(e){ var time = new Date().getTime(); var regexp = new RegExp($(this).data('id'), 'g'); var content = $(this).data('fields').replace(regexp, time); $(target).append(content); e.preventDefault(); }); 

现在是一个视图调用:

 <%= form_tag .... do |f| 
<%= link_to 'Add an Organisation', '#', class: 'add-fields', data: data_for_field(f, :degrees, path: "/degrees/fields").merge(target: "#list") %> <% end %>

现在创建一个部分,其中使用学位字段。

/degrees/_fields.html.erb

 <%= content_tag :div do %> <%= f.input :name %> <% end %> 

现在说明一下:

对于data_for_field,您传递:f(form),:degrees(关联模型的复数名称作为符号),以及任何其他选项,例如字段partial的路径。 它基本上创建了表单字段的脚手架,并将它们设置为“添加限定”链接上的数据属性。 我已经合并了一个数据目标,该数据目标的css ID也是将新字段插入页面的位置。

单击JS事件时会触发并使用时间戳替换表单字段中的id,因此对于每个限定条件,您将拥有唯一键。

我通常也有一些额外的JS事件来删除字段。

希望这可以帮助。

这是一个多态嵌套关联,可以使用javascript在客户端处理。 所以,最后对于嵌套字段,我使用了插件Numerous.js 。 只需按照链接的qucikstart部分中给出的步骤,从Github下载many.js文件并保存到assets / javascripts。

在我的代码中,

profile.rb

 class Profile < ApplicationRecord has_many :degrees, :as => :degreeable accepts_nested_attributes_for :degrees, :reject_if => :all_blank, allow_destroy: true belongs_to :user, :class_name => 'User', :foreign_key => 'user_id' end 

degree.rb

 class Degree < ApplicationRecord belongs_to :degreeable, polymorphic: true end 

型材/ _form.html.erb

  
<%= f.fields_for :degrees, Degree.new, :child_index => 'replace_this' do |degree_form| %> <%= degree_form.select :level, options_for_select(Job::EDUCATION, params[:level]), include_blank: "Select Degree", :class => 'span5' %> <%= degree_form.text_field :description, placeholder: "Add a new Degree here..."%> <%= link_to 'x Remove', '#', :class => 'numerous-remove', type: 'button' %> <% end %>
<%= link_to (fa_icon 'plus').to_s + 'Add a Qualification', '#', :id => 'add-to-list' %>

最后,有了强大的参数,

  def profile_params params.require(:profile).permit(:user_id, :first_name, :last_name, degrees_attributes:[:id, :level, :description]) end 

请注意,我已经为多态关联设置了2个额外字段的设置度表: - "degreeable_id" & "degreeable_type" ,当输入DB时,这两个字段自动填充了新创建的profile_id和'Profile'(名称)多态与程度相关联的模型)。

many.js中的技巧是使用唯一的临时ID(如Time.now.to_i)创建每个嵌套的表单记录(此处为度),因此现在在客户端创建/销毁的每个度数记录都将具有diff degree_attribute'id'。 希望它能帮助别人。