I have 2 tables, Item and ItemBelonging. I'm trying to create tree relationships between items. For every descendant of an item I create a item_belonging to join the item and the descendent item.
Item {
id:,
...
}
ItemBelonging {
id:,
item_id:,
descendant_id:,
...
}
I am able to successfully call item.descendants to receive all descendants of an item. I have set up the relationships like this:
class ItemBelonging < ApplicationRecord
belongs_to :descendant, :class_name => 'Item'
...
end
class Item < ApplicationRecord
has_many :descendants, :through => :item_belongings, :source => :descendant
...
end
The problem is that I would like to be able to call item.ancestors to get all ancestors of an item using the same ItemBelonging relationship. I am able to do this like so:
def ancestors
Item.joins(:item_belongings).where("item_belongings.descendant_id = ?", id)
end
But how do I create this relationship using has_many/belongs_to? This does not work:
class ItemBelonging < ApplicationRecord
belongs_to :descendant, :class_name => 'Item'
belongs_to :ancestor, :class_name => 'Item', :foreign_key => :item_id
...
end
class Item < ApplicationRecord
has_many :descendants, :through => :item_belongings, :source => :descendant
has_many :ancestors, :through => :item_belongings, :source => :ancestor, :foreign_key => :descendant_id
...
end
My end goal is to be able to call Item.includes(:descendants) and Item.includes(:ancestors). How do I get the ancestors relationship working?
With ancestry gem you can easily use such DSL
And then create few records
And use such methods out of box