Rails - 单个属性的多个条目

Rails - Multiple entries for a single attribute

我在Rails 4.我用的是Simple Form。

我有个人资料模型和资格模型。

协会是:

profile.rb

belongs_to :profile

qualifications.rb

has_many :qualifications  

我的个人资料视图中有一个表格,其中包括我的资格视图中的表格的一部分。

配置文件#form

<%= simple_form_for(@profile) do |f| %>
            <%= f.error_notification %>

              <div class="form-inputs">

          <div class="row">

            <div class="intpol2">
              Your professional qualifications
            </div>

              <%= render 'qualifications/form', f: f %>     

          </div>

资格#表格

<%= simple_fields_for :qualification do |f| %>

  <div class="form-inputs">


    <div class="row">
        <div class="col-md-6">
            <%= f.input :title, :label => "Your award" %> 
        </div>

        <div class="col-md-6">


        </div>


    </div>

    <div class="row">
        <div class="col-md-6">
            <%= f.input :level,   collection: [ "Bachelor's degree", "Master's degree", "Ph.D", "Post Doctoral award"] %>
        </div>


        <div class="col-md-6">
        <%= f.input :year_earned, :label => "When did you graduate?", collection: (Date.today.year - 50)..(Date.today.year) %>
        </div>

  </div>

用户可能拥有不止一个学位。我想添加一个字段,它是一个显示 'add another qualification' 的按钮,然后可以使用一组新的资格表单字段。

我发现这个 post 试图做一些稍微不同的事情。我不想要 10 组空白的表单字段(这会使表单看起来太长)。

Creating multiple records for a model in a single view in Rails

还有其他方法可以实现吗?

看来你必须使用嵌套形式。您必须尝试您的 link 教程,因为我也会用到它。对于另一个教程,您可以将其用作参考 nested_forms-rails-4.2.

希望对你有所帮助。

您将寻找一个名为 cocoon; you can also watch this Railscast (Nested forms) 的 gem,它已经过时了,但仍然很好地解释了结构。


模式非常简单,但需要一些额外的部分:

  1. Have an ajax button which calls the controller
  2. The controller needs to return a form and built fields_for
  3. You'll use JS to append the new fields_for to the original form

最大的问题是新 fields_forid - 此模式的新实现使用 child_index: Time.now.to_i

我已经写过这个 here

这是一个新版本:


Ajax

首先,您需要一个 "Add Qualification" 按钮,它通过 ajax:

链接到您的控制器
#app/views/profiles/_form.html.erb
<%= simple_form_for(@profile) do |f| %>
    <%= f.error_notification %>
    <div class="form-inputs">
       <div class="row">
         <div class="intpol2">Your professional qualifications</div>
         <%= render 'qualifications/form', f: f %>     
       </div>
    </div>
       <%= button_to "+", new_profile_path, method: :get %>
<% end %>

控制器

这将通过 new 控制器方法,我们应该能够管理 return ajax 请求的特定响应:

#app/controllers/profiles_controller.rb
class ProfilesController < ApplicationController
   respond_to :js, :html, only: :new
   def new
      @profile = Profile.new
      @profile.qualifications.build
      respond_with @profile #-> will invoke app/views/profiles/new.js.erb
   end
end

回应

一旦您的 new.js.erb 被触发,我们需要构建新的 HTML 表单,提取 fields_for 并将其附加到您的视图:

#app/views/profiles/new.js.erb
var fields_for = $("<%=j render "profiles/form" %>").html(); //-> might need tweaking
$(fields_for).appendTo("#new_profile.form-inputs");

child_index

您还应该更改 qualifications/form 以包含 child_index:

#app/views/qualifications/form.html.erb
<%= simple_fields_for :qualifications, child_index: Time.now.to_i do ...

子索引表示 fields_for 个元素中的 index 个。在我们的例子中(因为我们正在制作所有新记录),这无关紧要。使用 Time.now.to_i 确保每次都是完全唯一的 id


最后,您需要确保您拨打的是:

 <%= simple_fields_for :qualifications ... %> 

...复数