Reputation: 4752
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
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