ruby-on-railsactiverecordrails-activerecordhas-many-through

Create Record With "has_many_through" Association – Ruby on Rails


I have a has_many_through association where Users have many Projects through ProjectUsers. Rails has some magic that allows updating this relationship with:

u = User.first
u.update(project_ids: [...])

Is there a clean way to do the same thing with create?

Running User.create(name: ..., project_ids: [...]) fails with Validation failed: Project users is invalid.

I suspect this is because Rails tries to create the ProjectUser record before creating the User record and has some built-in validation on join tables to validate that both sides of the join already exist. The ProjectUser model has no custom validation.

class ProjectUser < ApplicationRecord
  belongs_to :project
  belongs_to :user
end

Is there a simple way to get around this?


Solution

  • Active Record supports automatic identification for most associations with standard names. However, Active Record will not automatically identify bi-directional associations that contain the :through or :foreign_key options. (You can check here)

    So you have to define inverse_of explicitly.

    class Project < ApplicationRecord
      has_many :project_users, foreign_key: :project_id, inverse_of: :project
      has_many :users, through: :project_users
    end
    
    class User < ApplicationRecord
      has_many :project_users, foreign_key: :user_id, inverse_of: :user
      has_many :projects, through: :project_users
    end
    
    class ProjectUser < ApplicationRecord
      belongs_to :project
      belongs_to :user
    end