Search code examples
ruby-on-railsruby-on-rails-4activerecordnested-attributes

Rails accepts_nested_attributes_for associated models not created


I have two models (Company and User) that have a belongs_to/has_many relationship.

class Company < ActiveRecord::Base
    attr_accessor :users_attributes
    has_many :users
    accepts_nested_attributes_for :users, allow_destroy: true
end

class User < ActiveRecord::Base
    belongs_to :company
end

In my CompaniesController I want to create a new instance of Company along with a group of Users.

class Cms::CompaniesController < ApplicationController
    def create
        company = Company.new(company_params)

        respond_to do |format|
            if company.save
                format.json { render json: company, status: :ok }
            else
                format.json { render json: company.errors.messages, status: :bad_request }
            end
        end
    end

    private

    def company_params
        params.require(:company).permit(
            :id, 
            :name, 
            users_attributes: [
                :id,
                :_destroy,
                :first_name,
                :last_name,
                :email
            ]
        )
    end
end

When I call company.save, I would expect a new instance of Company along with several new instances of User to be saved, depending on how many users I have in my params, however no users are persisted.

Here is a sample of what company_params looks like:

{"id"=>nil, "name"=>"ABC", "users_attributes"=>[{"first_name"=>"Foo", "last_name"=>"Bar", "email"=>"foo@bar.com"}]}

What am I missing here?


Solution

  • Remove attr_accessor:

    class Company < ActiveRecord::Base
        has_many :users
        accepts_nested_attributes_for :users, allow_destroy: true
    end
    

    Everything else should work.

    --

    attr_accessor creates getter/setter methods in your class.

    It's mostly used for virtual attributes (ones which aren't saved to the database). Your current setup is preventing you from being able to save the users_attributes param, thus your users are not saving.