If you’re a responsible / anal Rails dev you’ll probably want to include foreign key validations in your join models, b/c what’s a the point of a join model that doesn’t join anything? Well, maybe you’re working on some kind of pork barrel project building models to nowhere. I suppose that could happen. Maybe. I hope not. Anyway, example:

class ProjectObservationField < ActiveRecord::Base
  belongs_to :project
  belongs_to :observation_field
  validates :project, :presence => true
  validates :observation_field, :presence => true
end

And if you make a lot of forms you’ve probably run into accepts_nested_attributes_for, e.g.

class Project < ActiveRecord::Base
  has_many :project_observation_fields
  accepts_nested_attributes_for :project_observation_fields
end

Combining these two leads to sadness: Rails will try to validate the presence of the associate in the join record before that associate exists in the database, so in this case, the validation on the ProjectObservationField will get run before that record is assigned an associated Project.

The solution:

class ProjectObservationField < ActiveRecord::Base
  belongs_to :project, :inverse_of => :project_observation_fields
  belongs_to :observation_field, :inverse_of => :project_observation_fields
  validates :project, :presence => true
  validates :observation_field, :presence => true
end
 
class Project < ActiveRecord::Base
  has_many :project_observation_fields, :inverse_of => :project
  accepts_nested_attributes_for :project_observation_fields
end

:inverse_of makes Ruby smarter about nested attributes, as has been documented here. For whatever reason my normal reflexive Googling / StackOverflowing did not turn this up, and thus, I am writing a silly blog post.