ClosureTree/closure_tree

how to have children with multiple parents?

Sujimichi opened this issue · 2 comments

How would one go about setting up a the association to model a human (or any organic) family tree, where each node has two parents? Is this possible with closure_tree?

I have a Human class and in my initial setup (with a simple self join) I had:

class Human < ApplicationRecord
  belongs_to :father, class_name: "Human", optional: true
  belongs_to :mother, class_name: "Human", optional: true

  has_many :fathered_offspring, class_name: "Human", foreign_key: :father_id
  has_many :mothered_offspring, class_name: "Human", foreign_key: :mother_id
    
    
  def offspring
    self.mothered_offspring.or(self.fathered_offspring)
  end
end

This works, in that a human can have human.mother and human.father and both mother and father can call .offspring
But obv this setup will become horribly inefficient when trying to draw large family trees, so I'm looking to see if closure_tree could help.

If I add to my existing Human model

has_closure_tree parent_column_name: :father_id

Then closure_tree works for the paternal line. But how would I set about adding a maternal line?
I optimistically tried adding has_closure_tree parent_column_name: :mother_id after the first has_closure_tree but that (not surprisingly) didn't work.

Is having multiple parents possible with closure_tree? If not, is there a standard, conventional way to approach this sort of problem?

ryanb commented

I had a need for multiple parents too. I saw issue #22 which mentions this is currently not supported by closure tree.

I ended up bypassing closure tree entirely for this. Here's a gist of my solution for multiple parents.

It involves an "edge" join model so it can support multiple parents. Since your constraint is two parents per node there may be a better solution.

@ryanb ! Thanks for railscasts! I listened to those ages ago: great work.