Rails - Cocoon gem - 嵌套表单

时间:2015-12-31 00:03:08

标签: ruby-on-rails nested-forms nested-attributes cocoon-gem

我正在尝试使用Rails 4制作应用程序。

我对表单使用简单的表单gem,并尝试将Cocoon gem用于表单的嵌套元素。

我问过这个问题,这个问题解释了我想要更详细地实现的目标:Rails - Multiple entries for a single attribute

我有个人资料模型和资格模型。协会是:

profile.rb

has_many :qualifications  
    accepts_nested_attributes_for :qualifications,  reject_if: :all_blank, allow_destroy: true

qualification.rb

belongs_to :profile

配置文件控制器包含强参数中的限定属性:

def profile_params
      params[:profile].permit(:user_id, :title, :hero, :overview, :research_interest, :occupation, :external_profile, 
        :working_languages, :tag_list,
          qualifications_attributes: [:id, :level, :title, :year_earned, :institution, :_destroy] )
    end

我的个人资料表单现在有:

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

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

          </div>
          <div class="row">
            <div class="col-md-6">
              <%= link_to_add_association 'Add a qualification', f: f,  partial: 'qualifications/qualification_fields' %>

            </div>

我的资格部分表格现在在我的资格认证文件夹中命名为_qualifications_fields.html.erb

<div class="nested-fields">
<div class="container-fluid">

        <%= simple_fields_for :qualifications 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>


          <div class="row">
                <div class="col-md-6">
                     <!-- link_to_remove_association 'Remove this qualification', f, :f  -->
                </div>

          </div>


          </div>
        <% end %>
</div>  
</div>      

我注释掉了删除链接,因为我得到了这个错误:

undefined method `new_record?' for nil:NilClass

我对Rails报告错误的方式感到困惑 - 我很少理解这种风格的错误信息,但我认为它与没有任何移除资格有关。茧是否能解决这个问题?

当我对此进行评论并再次尝试时,我会通过添加关联的链接收到此错误:

undefined method `object' for #<Hash:0x007fe70c501ea0>

我不知道这条消息的含义。

因此,按照Cocoon gem文档中的步骤进行操作(由于我不知道如何用haml编写内容,所以更改表达形式以引用表单生成器&f; f: f&#39;在我的其他表单中工作,所以我猜测文档中显示的表达式可能与haml有关),我在这个阶段有2个错误:

  1. 添加关联 - 未定义的方法对象
  2. 删除关联 - 未定义的方法`new_record?
  3. 我很难理解这里发生了什么。

    采取JEIWAN的建议:

    我将个人资料表单更改为:

        <%= simple_form_for @profile, html: { multipart: true }  do |f| %>
                <%= f.error_notification %>
    
                  <div class="form-inputs">
    
    
              <div class="row">
    
                <div class="intpol2">
                  Your professional qualifications
                </div>
                <%= simple_fields_for :qualifications do |f| %>
    
                  <%= render 'qualifications/qualification_fields', f: f %>  
    
                </div>
              <div class="row">
                <div class="col-md-6">
    
                   <%= link_to_add_association 'Add a qualification', f, :qualifications, partial: 'qualifications/qualification_fields' %>
                <% end %>
                </div>
    
              </div>
    
                  <div class="form-actions">
                    <%= f.button :submit, "Submit", :class => 'formsubmit' %>
                  </div>
            <% end %>
        </div>
      </div>    
    </div>      
    

    我将资格字段格式更改为:

    <div class="nested-fields">
    <div class="container-fluid">
    
              <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>
    
    
              <div class="row">
                    <div class="col-md-6">
                        <%= link_to_remove_association 'Remove this qualification', f %>
                    </div>
    
              </div>
    
    
              </div>
    
    </div>  
    </div>      
    

    当我保存并重试时,我收到此错误:

    undefined method `new_record?' for nil:NilClass
    

    错误消息突出显示以下行:

                <%= link_to_remove_association 'Remove this qualification', f %>
    

1 个答案:

答案 0 :(得分:2)

link_to_add_association 'Add a qualification', f: f,  partial: 'qualifications/qualification_fields'

f: f在这里不正确。第二个参数应该是表单构建器(只是一个对象,而不是哈希)和第三个参数 - 关联的名称,即您的案例中的:qualifications。所以看起来应该是这样的:

link_to_add_association 'Add a qualification', f, :qualifications, partial: 'qualifications/qualification_fields'

在这里:

link_to_remove_association 'Remove this qualification', f, :f

:f也错了。这里的第三个参数是HTML选项。如果您不需要它们,那么只需指定2个参数:

link_to_remove_association 'Remove this qualification', f

接下来,_qualification_fields.html.erb不应包含simple_fields_for。此partial用于呈现一个不同关联对象的字段。当您点击“添加资格”时会显示该信息。或者当您的父对象已具有某些资格时。 simple_fields_for :qualifications应放在您的个人资料表单中,并包含render 'qualifications/qualifications_fields', f: flink_to_add_association ...。请考虑以下示例:https://github.com/nathanvda/cocoon#simpleform