Daniel
Daniel

Reputation: 75

Conditional polymorphic association with has many through

I have a tricky association structure between models and I can't figure out how to implement this.

I have policies, and each policy has policy participants.

These policy participants can be either persons or companies and have a specific type, for example insuree or contributor. Each policy has exactly one policy participant of each type.

What I have so far:

class Policy < ActiveRecord::Base
  has many :policy_participants

  # insuree
  has_one :insuree_participant, -> { insuree }, class_name: 'PolicyParticipant'
  has_one :insuree, through: :policy_participants, -> { where(role: 1) }, source: :participant
end

class PolicyParticipant < ActiveRecord::Base
  belongs_to :policy
  belongs_to :participant, polymorphic: true
  enum role: { insuree: 1, contributor: 2, etc: 3 }
end

class Person < ActiveRecord::Base  # same for Company.rb
  has_many :policy_participations, as: :participant
  has_many :insuree_policy_participations, -> { insuree }, as: :participant
end

In the rails console, when I try policy.insuree, I get this error:

ActiveRecord::HasManyThroughSourceAssociationNotFoundError: Could not find the source association(s) "insuree" or :insuree in model PolicyParticipant. Try 'has_many :insuree, :through => :policy_participants, :source => '. Is it one of policy, participant, type, address, person, or company?

I thought about a parent class for person and company, but as there is only the name in common, I'd rather avoid doing this.

Can someone help me?

Upvotes: 1

Views: 813

Answers (1)

Mark Swardstrom
Mark Swardstrom

Reputation: 18080

I think this line needs to change

has_one :insuree, through: :policy_participants, -> { where(role: 1) }, source: :participant

to

has_one :insuree, -> { where(role: 1) }, through: :policy_participants, source: :participant

The lambda (or scope) needs to be the first param to has_one

Upvotes: 1

Related Questions