Rails - Cocoon gem - Nested Forms

廉价感情. 提交于 2019-12-12 18:38:30

问题


I am trying to make an app with Rails 4.

I use simple form gem for forms and am trying to use Cocoon gem for nested elements of the forms.

I asked this question, which explains what I'm trying to achieve in more detail: Rails - Multiple entries for a single attribute

I have a profile model and a qualifications model. The associations are:

profile.rb

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

qualification.rb

belongs_to :profile

the profiles controller includes the qualification attributes in the strong params:

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

My profile form now has:

 <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>

My qualifications partial form is now named in my qualification views folder as _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>      

I commented out the remove link, because as is, I get this error:

undefined method `new_record?' for nil:NilClass

I'm baffled by the way Rails reports errors- I rarely understand error messages of this style, but I gather it's something to do with there not being any qualifications to remove. Does cocoon handle this?

When I comment this out and try again, I get this error with the link to add an association:

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

I don't know what this message means either.

So, by following the steps in the Cocoon gem docs, (with changes because I don't know how to write things in haml; and changing the form of expression to reference the form builder 'f: f' works across the rest of my forms, so Im guessing that the expression shown in the docs might be something to do with haml), I have 2 errors at this stage:

  1. add association - undefined method object
  2. remove association - undefined method `new_record?

I'm struggling to understand what's going on here.

TAKING JEIWAN'S SUGGESTION:

I change my profile form to:

    <%= 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>      

I change my qualification fields form to:

<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>      

When I save this and try again, I get this error:

undefined method `new_record?' for nil:NilClass

The error message highlights this line:

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

回答1:


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

f: f is incorrect here. The second parameter should be a form builder (just an object, not a hash) and the third parameter – the name of the association, i.e. :qualifications in your case. So it should look like this:

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

And here:

link_to_remove_association 'Remove this qualification', f, :f

:f is also wrong. Third parameter here is HTML options. If you don't need them, then just specify 2 parameters:

link_to_remove_association 'Remove this qualification', f

Next, _qualification_fields.html.erb shouldn't contain simple_fields_for. This partial is used to render the fields of one distinct association object. It is shown when you click 'Add a qualification' or when your parent object already has some qualifications. simple_fields_for :qualifications should be put in you profile form and contain render 'qualifications/qualifications_fields', f: f and link_to_add_association .... Consider this example: https://github.com/nathanvda/cocoon#simpleform



来源:https://stackoverflow.com/questions/34539157/rails-cocoon-gem-nested-forms

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!