Same Model for Two belongs_to Associations

17,106

Solution 1

Thanks to jamesw over at RailsForum.com: Same Model for Two belongs_to Associations a solution has been found.

class System < ActiveRecord::Base
  belongs_to :project_manager, :class_name => 'PointOfContact', :foreign_key => 'project_manager_id'
  belongs_to :technical_manager, :class_name => 'PointOfContact', :foreign_key => 'technical_manager_id'
end

class PointOfContact < ActiveRecord::Base
  has_many :project_managed_systems, :class_name => 'System', :foreign_key => 'project_manager_id'
  has_many :technical_managed_systems, :class_name => 'System', :foreign_key => 'technical_manager_id'
end

Solution 2

From the Rails documentation:

Annotated example:

# Employee class with two Employee associations
class Employee < ApplicationRecord

  # Employees I manage
  has_many :subordinates, class_name: "Employee",
                          foreign_key: "manager_id"

  # Employee that manages me
  # NOTE: with :manager reference name, foreign_key defaults to "manager_id",
  # hence it is not needed as above. Favor "convention over configuration".
  belongs_to :manager, class_name: "Employee"
end
Share:
17,106

Related videos on Youtube

Ryan
Author by

Ryan

Software developer interested in Swift and Typescript.

Updated on March 07, 2020

Comments

  • Ryan
    Ryan over 4 years

    I have an model PointOfContact which has_many Systems. From the Systems side I want to identify the PointOfContact as either the technical_manager or project_manager (or both). While still only keeping the PointOfContact 1 time in the DB.

    My attempt follows:

    class System < ActiveRecord::Base
      belongs_to :project_manager, :class_name => 'PointOfContact'
      belongs_to :technical_manager, :class_name => 'PointOfContact'
    end
    
    class PointOfContact < ActiveRecord::Base
      has_many :systems
    end
    

    When I run my specs (example follows) I can correctly create the System point of contact associations. However, the PointOfContact is not aware of its association with System. Why is that?

    @sys = System.create
    @tm = PointOfContact.create
    @pm = PointOfContact.create
    
    @sys.project_manager = @pm
    @sys.technical_manager = @tm
    
    @pm.systems.should have(1).items #> expected 1 items, got 0
    
  • Zippie
    Zippie over 11 years
    more details on :through relationships on link