Home > Net >  Rails Mass Assign has_and_belongs_to_many
Rails Mass Assign has_and_belongs_to_many

Time:03-16

I'm getting this error when I try to mass-assign a HABTM relationship in Rails 5:

*** ActiveRecord::RecordNotFound Exception: Couldn't find Job with ID=6 for Profile with ID=

class Profile < ApplicationRecord
  has_and_belongs_to_many :jobs
  accepts_nested_attributes_for :jobs
end

class Job < ApplicationRecord
  has_and_belongs_to_many :profiles
end

class ProfilesController < ApplicationController

  def create
    @profile = Profile.new(profile_params)
  end

  private

    def profile_params
      params.require(:profile).permit(
        :name,
        :email,
        :jobs_attributes: [:id]
      )
    end
end

=form_for @profile do |f|
  =f.fields_for :jobs do |j|
    =j.select :id, options_for_select([[1, "Job 1", ...]])

CodePudding user response:

The problem is that accepts_nested_attributes_for is a way to update attributes on an associated object (either already linked or one that you're creating). You can think of it doing something like:

params[:jobs_attributes].each do |job_attributes|
  @profile.jobs.find(job_attributes[:id]).attributes = job_attributes
end

Except that the job is then saved with the new attributes in an after-save of the parent object.

This isn't what you want. In fact, you don't need accepts_nested_attributes at all.

Instead, change the attribute in your view to job_ids as if it's an attribute of the profile, something like the following:

=form_for @profile do |f|
  =j.select :job_ids, options_for_select([[1, "Job 1", ...]])

This will effectively call profile.job_ids = [1,2,3] which will have the effect that you're looking for.

  • Related