【问题标题】:Rails nested polymorphic form with javascripting带有javascripting的Rails嵌套多态形式
【发布时间】:2017-02-28 07:57:20
【问题描述】:

我希望在我的表单上显示以下内容:

Degree 是与 profile 有 has_many 关系的多态部分。这个部分被主要形式 - 配置文件调用。通过按“添加资格”,用户可以添加尽可能多的学位。我只能在个人资料上附加一个学位,这是最后一个学位,其他学位都被忽略了。我什至知道为什么会这样,因为 link_to 无法传递配置文件实例。所以我必须在degrees_controller 中创建新的配置文件,正如您在我的code here 中看到的那样。提交“创建配置文件”时,最终配置文件实例是否可以拾取上述所有其他实例。

请提供任何帮助,以便我可以将所有学位都附在表格上,过去几天我一直坚持使用 SO 和谷歌的所有排列和组合。我什至已经准备好更改代码....对此的任何帮助将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    我有这个小帮手可以帮我解决这些案件。它可重复使用,因此您不必在同一个应用中针对不同情况编写所有这些内容。

    首先是代码:

    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(作为符号的关联模型的复数名称)以及任何其他选项,例如字段的部分路径。它基本上创建了表单字段的脚手架,并将它们设置为“添加资格”链接上的数据属性。我已经合并到一个数据目标中,它的 css ID 也是在页面中插入新字段的位置。

    当您单击 JS 事件时,触发并将表单字段中的 id 替换为时间戳,因此对于每个资格,您将拥有一个唯一的键。

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

    希望这会有所帮助。

    【讨论】:

    • 首先,谢谢丹。我不希望有人能帮忙,因为昨天我的问题没有得到任何答案。说实话,我很沮丧,我想完全放弃这个。其次,关于代码,如何调用data_for_field()?下面是link_to代码。 @profile.id },@degreeable.degrees.new),远程:真 %>。基本上我将学位设置为@job。
    • 抱歉 - 我没有正确缩进其中一个代码 sn-ps,由于某种原因使其不可见。我现在更新了答案,包括对 data_for_field() 的调用。
    • 我可能还应该提到这会自动使用 f.fields_for 基本上您不需要进行远程调用来加载其他表单字段。让我知道你的情况,很高兴为您提供帮助。
    • 嗨,丹,非常感谢。我出去玩了几天,但这是第一要务。我从没想过会花这么多时间....变幻莫测的编码。我必须在我的整体代码中合并多态性和 JS 部分,并删除其他部分并查看所有代码如何协同工作。当我遇到任何问题时,我会回复你。
    • 嗨,Dan,我已经执行了代码,但不幸的是,它根本没有显示 degree/_fields。我还想要 ajax(remote:true) 以便在按下按钮时,主配置文件表单不会重新加载。我不知道JS是否正在执行。请提出可能是什么问题。我真的很想让这个工作。
    【解决方案2】:

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

    学位.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
    

    请注意,我已经为多态关联设置了带有 2 个额外字段的学位表:-"degreeable_id" &amp; "degreeable_type" 并且在进入 DB 时,这两个字段自动填充了新创建的 profile_id 和“Profile”(多态性与度数相关联的模型)。

    众多.js 中的技巧是创建具有唯一临时 ID 的每个嵌套表单记录(此处为学位),例如 Time.now.to_i,因此现在在客户端创建/销毁的每个学位记录都将具有 diff degree_attribute 'id'。希望对其他人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 2014-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多