[JSON-API] Recursive has_many :children (include tree)
felixbuenemann opened this issue · comments
It should be possible to express recursive relationships using JSONAPI has_one/has_many.
Without has_one/has_many I could just use a self-referential collection:
class TaxonRepresenter < Roar::Decorator
include Roar::JSON::JSONAPI
LimitDepth = ->(user_options: {}, **) {
user_options[:depth] ? depth < user_options[:depth] : true
}
type :taxons
property :id
property :name
# ...
collection :children, extend: self, class: Taxon, if: LimitDepth
end
# Serialize up to depth 2
TaxonRepresenter.prepare(taxon).to_hash(user_options: { depth: 2 })
However has_one/has_many requires a block, so I can't just specify self
as the decorator.
After looking at the source of Roar::JSON::JSONAPI
I came up with this beautiful solution hack:
class TaxonRepresenter < Roar::Decorator
include Roar::JSON::JSONAPI
LimitDepth = ->(user_options: {}, **) {
user_options[:depth] ? depth < user_options[:depth] : true
}
type :taxons
property :id
class RelationshipRepresenter < self; end
property :name
# ...
nested :included do
collection :children, decorator: TaxonRepresenter, class: Taxon, if: LimitDepth
end
nested :relationships do
collection :children, decorator: RelationshipRepresenter, class: Taxon, if: LimitDepth
end
end
Surely there should be an easier solution, given that trees are not exactly uncommon.
I'm using roar master and representable 3.0.0.
After thinking some more about it. Shouldn't it be possible to call has_one/has_many without a block and then just pass decorator, class, erc as an option?
In most casey where I habe an association I will already have a usable decorator for the collection class.
This issue was moved to trailblazer/roar-jsonapi#9