using has_many :through and build

If you have a has_many :through association and you want to save an association using build you can accomplish this using the :inverse_of option on the belongs_to association in the Join Model

Here's a modified example from the rails docs where tags has a has_many :through association with posts and the developer is attempting to save tags through the join model (PostTag) using the build method:

@post = Post.first
@tag = @post.tags.build name: "ruby"
@tag.save

The common expectation is that the last line should save the "through" record in the join table (post_tags). However, this will not work by default. This will only work if the :inverse_of is set:

class PostTag < ActiveRecord::Base
  belongs_to :post
  belongs_to :tag, inverse_of: :post_tags # add inverse_of option
end

class Post < ActiveRecord::Base
  has_many :post_tags
  has_many :tags, through: :post_tags 
end

class Tag < ActiveRecord::Base
  has_many :post_tags
  has_many :posts, through: :post_tags  
end

So for the question above, setting the :inverse_of option on the belongs_to :user association in the Join Model (CompanyUser) like this:

class CompanyUser < ActiveRecord::Base
  belongs_to :company
  belongs_to :user, inverse_of: :company_users
end

will result in the following code correctly creating a record in the join table (company_users)

company = Company.first
company.users.build(name: "James")
company.save

Source: here & here


You can't use a has_many :through like that, you have to do it like this:

@company = Company.last
@user    = User.create( params[:user] ) 
@company.company_users.create( :user_id => @user.id )

Then you will have the association defined correctly.

update

In the case of the comment below, as you already have accepts_nested_attributes_for, your parameters would have to come like this:

{ :company => 
    { :company_users_attributes => 
        [ 
          { :company_id => 1, :user_id => 1 } ,
          { :company_id => 1, :user_id => 2 },
          { :company_id => 1, :user_id => 3 } 
        ]
    } 
}

And you would have users being added to companies automatically for you.