Search code examples
ruby-on-railsrubynested-attributes

using nested attributes in rails with cocoon


I have this setup and for some reason, I can't save the employent_history in the database. when the updated only the profile attributes are updated i used cocoon gem

class User < ApplicationRecord
  has_one :profile, dependent: :destroy
  has_many :employent_histories :through :profile
  after_create :init_profile

  def init_profile
    self.create_profile!
  end
end

As you can see the profile is created when a new user is created

I added another model called employment_history that belong to but user and profile

The Profile Model accepts_nested_attributes_for :employment_history

class Profile < ApplicationRecord
  belongs_to :user
  has_many :employent_histories
  accepts_nested_attributes_for :employent_histories
end

class EmploymentHistory < ApplicationRecord
  belongs_to :user 
  belongs_to :profile

 end

profile_controller.rb

There is no create action because the resource is created when a new user is ctreated

class ProfilesController < ApplicationController

  def show
    @profile = current_user.profile
  end


  def edit
      @profile = current_user.profile
  end


    def update
    # byebug
      @profile = current_user.profile
    respond_to do |format|
      if @profile.update profile_params
        format.html { redirect_to user_profile_path, notice: "Profile updated!" }
        format.json { render :edit, status: :ok, location: @profile }
      else
        format.html { redirect_to edit_user_profile_path, flash: { error: "Profile could not be updated!" } }
        format.json { render json: @profile.errors.messages, status: :unprocessable_entity }
      end
    end
  end

  private
  def profile_params
    params.require(:profile).permit(:title,:phone,:address,:zip_code,employment_histories:[:job_title,:employer,:_destroy])
  end

views/profiles/edit.html.erb

<%= form_for @profile, url: {action: "update"} do |f| %>
   <%= attributes%>
   <%= attributes%>
     <%= f.fields_for :employment_histories do |ff| %>
      <%= attributes%>
     <%end%>
<%f.sumbit%>
<%end%>

Using this setup , the fields for the nested attributes form does not display on the edit profile page. what am i missing


Solution

  • You are permitting :employment_histories in the params, but AFAIR, the nested params are supposed to be received under key :<association-name>_attributes.

    Also, you should permit the id of nested objects, in case you want to edit them again.

    So, the final profile_params should look like:

    def profile_params
      params.require(:profile)
            .permit(
              :title,
              :phone,
              :address,
              :zip_code,
              employment_histories_attributes: [:id, :job_title, :employer, :_destroy]
            )
    end