问题
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:
- add association - undefined method object
- 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