Rails使用javascripting嵌套多态形式

时间:2017-02-28 07:57:20

标签: ruby-on-rails partial polymorphic-associations

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

enter image description here

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

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

2 个答案:

答案 0 :(得分:0)

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

首先是代码:

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|
    <div id="list"></div>
    <%= link_to 'Add an Organisation', '#', class: 'add-fields', data: data_for_field(f, :degrees, path: "/degrees/fields").merge(target: "#list") %></p>
<% 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事件来删除字段。

希望这有帮助。

答案 1 :(得分:0)

这是一个多态嵌套关联,可以使用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

    <div id="fields-for-list" class="numerous">
      <%= 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 %>
   </div>
   <div id="list"></div>
   <%= 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",当在数据库中输入时,这两个字段自动填充了新创建的profile_id和'Profile'(名称)多态性与程度相关联的模型)。

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