I was looking for a solution to a legacy converted application and this ancestry appears close, but I have one design issue with the legacy that I need to understand if ancestry already handles, or if I need to start there and work similarly.
In my legacy application the tree structure supports a SINGLE TOP to the tree, but inside the tree nodes can have MULTIPLE parents. Mostly they do not have multiple parents, but that is allowed. So if A is the highest parent (called most distant ancestor in the legacy system model) then there is ONE and only ONE A. A could have children B, C and D. And it could have a child X which has children B and C. SO to be clear A has 4 direct children, and one of those is also the parent of 2 of those children, meaning the concept of depth is somewhat vague. X MUST be a child through some lineage of A.
I infer this is not current functionality of ancestry (i.e. multiple direct parents), given the discussions of "depth" which in my legacy model are vague and not relevant to the application. The application is really just concerned with for any given node 1) who are it's ancestorS and who are it's descendantS. So it is a tree with some network behavior. The legacy application itself prevents cyclic relationships, etc.
Any guidance or thoughts appreciated.
Ancestry is a gem to model trees: graphs without cycles. Ancestry does not, and will never handle graphs.
@tjchambers You could fork ancestry and add support for multiple parents, but that's not fairly easy I think.
I'm not sure if the data of the legacy application has to stay the same. Otherwise you could change the data structure in such a way that it becomes a tree; and then use ancestry to manage the tree.
But as @stefankroes said: there is no intention of supporting multiple parents. That's just out of the scope of this library.
I anticipated that would be the response, and after looking at the clean code I believe forking and adding that is the proper path. Changing the data structure would be possible, as I own the app, but the end result - which is that a node has multiple paths to a single parent, is functionality that is required. It is basically multiple tree structures with a common root.
I appreciate the response, and even more so the fine work on the current construction. Just to be clear my implementation does not allow for cycles in practice only multiple path to a common root. Not sure that I conveyed that properly in my initial query.
Tim - are you still working on this?
I am asking as I may have a solution, or two. One is to reclassify the data as unions. Where nodes are in fact paired into single unions of two nodes.
The other option is to build a simple or rich join table that accepts many to many relationships, either supplementing or replacing the ancestry functionality. I have a working example.
@MarkDK - sorry - thought it was @stefankroes asking me the question.
@tjchambers Do you still support your fork? I would love to use it in my project, but I am nervous about support for it disappearing. I have the same issue - needing to be able to allow 1 node to have multiple parents, and I like your solution of simply using an array/list of parent nodes. Did you also modify the various related methods, e.g. add a parents method, rather than a parent and likewise parent_ids versus just parent_id?
@marcamillion - My fork is in active use in a commercial application using Ruby 2.1 and Rails 4. So it is supported actively and does what that application needs. I have as would be expected adjusted the methods I require trying to be generic as possible to allow others to use this approach. I have also removed some methods that would not be easy to establish "correctness" and are not needed for me such as ones dealing with depth (my objects obviously can be at multiple depths).
Originally my parallel PHP application had a different column format and for a period of time up until about a year ago I had 2 ancestry columns (one for the old PHP code and one for the ruby code using this gem to point to the same tree structure). As of a year ago the PHP application changed to rely on my forked gems ancestry column solely so it is now even more critical that my fork work and is maintained.
Bottomline is my fork from the original (thanks so very much to @stefankroes for the foundation) does what I need it to do. I welcome your analysis and any pull requests to it that are compatible with my applications needs. I have tried also to maintain the test suite accordingly.
I must declare that I am a relative novice to Ruby - only 3 years of usage, but 40 years of development experience.
@tjchambers That sounds awesome. Based on the little poking around I have been doing, your fork looks good. Would you mind opening issues on your fork, so if there are any issues we can discuss them there? Thanks.
@marcamillion I am fine with you opening issues on the fork. I believe they are enabled.
@tjchambers Yep...just saw that. Thanks!