stefankroes / ancestry

Organise ActiveRecord model into a tree structure
MIT License
3.72k stars 458 forks source link

Multi-tenant with multiple roots issue calling siblings #590

Closed wooly closed 1 year ago

wooly commented 1 year ago

We have a scenario where we have a multi-tenanted application with each tenant having a set of roots with children (i.e. no singular root node).

Is it possible to scope all of the ancestry queries to a single-tenant as we're currently seeing calls to root.siblings crossing the tenant boundary?

I'd rather not introduce an unnecessary super-root type from which our client 'roots' descend, since we'd have to special case a lot of our tree logic. I'd also rather not introduce a default_scope to the model. Is there another approach?

Cheers!

kbrock commented 1 year ago

@wooly how are you currently scoping your nodes for queries?

This is tricky as we pop out of queries to support STI. This behavior may prove troublesome to you.

Can you create a query like how you are using the product? Are you throwing scopes on things or using default queries or other way?

kbrock commented 1 year ago

@wooly so you are asking that siblings for a root node does not return other root nodes?

wooly commented 1 year ago

Apologies @kbrock, I missed the original comment on the 8th November.

I feel like your most recent comment is the crux of it - that siblings for a root node would not return other root nodes, since they're distinct trees. That would allow you to model multiple trees using the same table and not have the siblings method cross to different trees. This is obviously a breaking change, though.

kbrock commented 1 year ago

@wooly I believe this may be a necessary breaking change.

It seems a little strange that root of trees have siblings

kbrock commented 1 year ago

Hello @wooly I just checked out closure_trees gem and they seem to have root nodes return other root nodes as siblings. Tabling this for now.

The best solution I can think of:

Model node = Model.roots.first

puts node.root? ? Model.none : node.siblings

Best of luck