Rails 使用 JavaScript 的嵌套多态形式
Rails nested polymorphic form with javascripting
我希望在我的表格中包含以下内容:
学位是多态性的部分,与个人资料有 has_many 关系。此部分由主窗体调用 - 配置文件。按 'Add a Qualification' 用户可以添加任意多的度数。我只能将一个学位附加到个人资料上,这是最后一个,其他的都被忽略了。我什至知道为什么会这样,因为 link_to 无法传递配置文件实例。所以我必须在 degrees_controller 中创建新的配置文件,正如您在我的 code here 中看到的那样。提交时最终配置文件实例是否可以提取上述所有其他实例'Create Profile'。
请提供任何帮助,以便我可以将所有学位附加到表格上,最近几天我一直坚持使用 SO 和 google 的所有排列和组合。我什至准备好更改代码....任何对此的帮助将不胜感激。
我有这个小帮手来帮助我解决这些案件。它是可重用的,因此您不必在同一个应用程序中为不同的情况编写所有这些东西。
首先是代码:
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(表单)、:degrees(作为符号的关联模型的复数名称)以及任何其他选项,例如字段的部分路径。它基本上创建了表单字段的脚手架,并将它们设置为 "Add Qualification" link 上的数据属性。我合并了一个数据目标,它具有 css ID,用于将新字段插入页面的位置。
当您单击 JS 事件时,将触发并用时间戳替换表单字段中的 ID,因此对于每个资格,您将拥有一个唯一的键。
我通常还会有一些额外的 JS 事件来删除字段。
希望对您有所帮助。
这是一个多态嵌套关联,可以在客户端使用 javascript 进行处理。因此,最后对于嵌套字段,我使用了插件 Numerous.js。只需按照 link 的 qucikstart 部分给出的步骤,从 Github 下载 numerous.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
profiles/_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
请注意,我已经设置了 degree table 和 2 个用于多态关联的额外字段:- "degreeable_id" & "degreeable_type"
并且在进入 DB 时,这两个字段自动填充了新创建的 profile_id 和 'Profile'(与度多态关联的模型的名称)。
numerous.js 中的技巧是创建每个嵌套表单记录(这里是学位),并使用唯一的临时 ID,例如 Time.now.to_i,所以现在客户端的每个学位记录 created/destroyed 都会有一个差异 degree_attribute 'id'。希望对其他人有帮助。
我希望在我的表格中包含以下内容:
学位是多态性的部分,与个人资料有 has_many 关系。此部分由主窗体调用 - 配置文件。按 'Add a Qualification' 用户可以添加任意多的度数。我只能将一个学位附加到个人资料上,这是最后一个,其他的都被忽略了。我什至知道为什么会这样,因为 link_to 无法传递配置文件实例。所以我必须在 degrees_controller 中创建新的配置文件,正如您在我的 code here 中看到的那样。提交时最终配置文件实例是否可以提取上述所有其他实例'Create Profile'。
请提供任何帮助,以便我可以将所有学位附加到表格上,最近几天我一直坚持使用 SO 和 google 的所有排列和组合。我什至准备好更改代码....任何对此的帮助将不胜感激。
我有这个小帮手来帮助我解决这些案件。它是可重用的,因此您不必在同一个应用程序中为不同的情况编写所有这些东西。
首先是代码:
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(表单)、:degrees(作为符号的关联模型的复数名称)以及任何其他选项,例如字段的部分路径。它基本上创建了表单字段的脚手架,并将它们设置为 "Add Qualification" link 上的数据属性。我合并了一个数据目标,它具有 css ID,用于将新字段插入页面的位置。
当您单击 JS 事件时,将触发并用时间戳替换表单字段中的 ID,因此对于每个资格,您将拥有一个唯一的键。
我通常还会有一些额外的 JS 事件来删除字段。
希望对您有所帮助。
这是一个多态嵌套关联,可以在客户端使用 javascript 进行处理。因此,最后对于嵌套字段,我使用了插件 Numerous.js。只需按照 link 的 qucikstart 部分给出的步骤,从 Github 下载 numerous.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
profiles/_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
请注意,我已经设置了 degree table 和 2 个用于多态关联的额外字段:- "degreeable_id" & "degreeable_type"
并且在进入 DB 时,这两个字段自动填充了新创建的 profile_id 和 'Profile'(与度多态关联的模型的名称)。
numerous.js 中的技巧是创建每个嵌套表单记录(这里是学位),并使用唯一的临时 ID,例如 Time.now.to_i,所以现在客户端的每个学位记录 created/destroyed 都会有一个差异 degree_attribute 'id'。希望对其他人有帮助。