问题
I'm trying to make an app with Rails 4.
I'm using Cocoon gem for nested forms with simple form.
I have a qualifications model, nested in a profile model. The associations are:
Qualifications
belongs_to :profile
Profile
has_many :qualifications
accepts_nested_attributes_for :qualifications, reject_if: :all_blank, allow_destroy: true
In my profile form, I incorporate the qualifications attributes with:
<%= f.simple_fields_for :qualifications do |f| %>
<%= render 'qualifications/qualification_fields', f: f %>
<% end %>
In my Qualifications form attributes, I have:
<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-8">
<%= f.input :pending, :label => "Are you currently studying toward this qualification?" %>
</div>
</div>
<div class="row">
<div class="col-md-4">
<%= f.input :level, collection: [ "Bachelor's degree", "Master's degree", "Ph.D", "Post Doctoral award"] %>
</div>
<div class="col-md-4">
<%= f.input :year_earned, :label => "When did you graduate?", collection: (Date.today.year - 50)..(Date.today.year + 5) %>
</div>
</div>
<div class="row">
<div class="col-md-6">
<%= link_to_remove_association 'Remove this qualification', f %>
</div>
</div>
</div>
</div>
</div>
In my profiles controller I have:
def new
@profile = Profile.new
@profile.qualifications_build
@profile.build_vision
@profile.build_personality
@profile.addresses_build
authorize @profile
end
# GET /profiles/1/edit
def edit
@profile.build_personality unless @profile.personality
@profile.qualifications_build unless @profile.qualifications
@profile.build_vision unless @profile.vision
@profile.addresses_build unless @profile.addresses
end
# POST /profiles
# POST /profiles.json
def create
@profile = Profile.new(profile_params)
authorize @profile
respond_to do |format|
if @profile.save
format.html { redirect_to @profile }
format.json { render :show, status: :created, location: @profile }
else
format.html { render :new }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /profiles/1
# PATCH/PUT /profiles/1.json
def update
# successful = @profile.update(profile_params)
# Rails.logger.info "xxxxxxxxxxxxx"
# Rails.logger.info successful.inspect
# user=@profile.user
# user.update.avatar
respond_to do |format|
if @profile.update(profile_params)
format.html { redirect_to @profile }
format.json { render :show, status: :ok, location: @profile }
else
format.html { render :edit }
format.json { render json: @profile.errors, status: :unprocessable_entity }
end
end
end
# DELETE /profiles/1
# DELETE /profiles/1.json
def destroy
@profile.destroy
respond_to do |format|
format.html { redirect_to profiles_url }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_profile
@profile = Profile.find(params[:id])
authorize @profile
end
# Never trust parameters from the scary internet, only allow the white list through.
def profile_params
params.require(:profile).permit( :title, :hero, :overview, :research_interest, :occupation, :external_profile,
:working_languages, :tag_list,
industry_ids: [],
user_attributes: [:avatar],
personality_attributes: [:average_day, :fantasy_project, :preferred_style],
vision_attributes: [ :long_term, :immediate_challenge],
qualifications_attributes: [ :level, :title, :year_earned, :pending, :institution, :_destroy],
addresses_attributes: [:id, :unit, :building, :street_number, :street, :city, :region, :zip, :country, :time_zone, :latitude, :longitude, :_destroy],
industries_attributes: [:id, :sector, :icon] )
end
end
My problems are:
when I save all of this and try it, each time I update the profile, it creates a new entry for the qualifications, so the list of qualifications displayed duplicates on every update (even when no update is made to the fields).
When I update the profile form and click remove qualification, it does not get removed from the array. I can delete them in the console, but not using the form.
I'm worried that if I remove
@profile.qualifications_build unless @profile.qualifications
from the edit action in the profile controller, I won't be able to update those attributes.
Also, it doesn't make sense to me that removing that would solve the problem with removing qualifications. Do I need to add something to the remove qualification link to force it to remove the entry?
回答1:
I think you just forgot to add :id
in the allowed parameters for qualifications, in your profile_params
:
qualifications_attributes: [ :id, :level, :title, :year_earned, :pending, :institution, :_destroy]
Without an ID to match, any qualification will be seen as a new one.
来源:https://stackoverflow.com/questions/34716057/rails-4-nested-attributes-with-cocoon-gem