Sergey
Sergey

Reputation: 4752

Rails has_many through multiple foreign keys

Given this:

class House < ApplicationRecord
  has_many :parents
  has_many :children, through: :parents
end

class Parent < ApplicationRecord
  belongs_to :house
  has_many :children, ->(parent) { unscope(:where).where("mother_id = :id OR father_id = :id", id: parent.id) }
end

class Child < ApplicationRecord
  belongs_to :mother, class_name: 'Parent'
  belongs_to :father, class_name: 'Parent'
end

I'm trying to do:

Parent.last.children.count # WORKS
House.last.parents.count # WORKS
House.last.children.count # DOESN'T WORK

no such column: children.parent_id: SELECT COUNT(*) FROM "children" INNER JOIN "parents" ON "children"."parent_id" = "parents"."id" WHERE (mother_id = 1 OR father_id = 1)

Is there any way to fix has_many :children, through: :parents? It should return children as ActiveRecord::Associations::CollectionProxy (not an Array). Perhaps some clever join?

Upvotes: 1

Views: 538

Answers (1)

Mahmoud Sayed
Mahmoud Sayed

Reputation: 668

the default join in has_many :children in house.rb is between the children and parents table depending on the parent_id column that is not exist.

so you need to override it: so house.rb should look like below.

class House < ApplicationRecord
  has_many :parents
  has_many :children, -> { unscope(:joins).joins('INNER JOIN ON children.father_id = parents.id OR children.mother_id = parents.id') }, through: :parents
end

Upvotes: 4

Related Questions