Multiple parents #94

Closed
tjchambers opened this Issue Jul 2, 2012 · 17 comments

Projects

None yet

6 participants

@tjchambers

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.

Owner

Ancestry is a gem to model trees: graphs without cycles. Ancestry does not, and will never handle graphs.

@stefankroes stefankroes closed this Jul 4, 2012
Contributor

@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.

Best Regards,

Tim

MarkDK commented May 21, 2014

Tim - are you still working on this?

I have implemented it in my fork.

On May 21, 2014, at 11:27, MarkDK notifications@github.com wrote:

Tim - are you still working on this?


Reply to this email directly or view it on GitHub.

MarkDK commented May 21, 2014

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.

I appreciate your thoughts on it.

My implementation was to take your base, eliminate some of the challenging aspects that would not apply in the multiple parent scenario, and add the multiple parent code by using a comma-separated list of parents in the same ancestry parent text field. so instead of a single slash delimited heirarchy it has a list ("1/2, 1/3,1/5") in the same field. I consider it a hack, but for my purpose it was not only adequate, but because the full path to the root (in my case a single root) was in the parent field, it allowed me to do some integrity checking that i lacked in my prior non-ruby implementation.

It also avoided the maintenance in my mixed PHP/RUBY product to be manageable until I eliminate the PHP portion (which is my active work project). '

Either of your 2 solutions seem doable. Although the join table seems easier to implement, but harder to traverse and validate.

Please note I am novice Ruby/Rails implementer so my judges should be taken with a pound of salt. I do however appreciate the headstart your base implementation provided very much.

Tim

On May 21, 2014, at 11:32, MarkDK notifications@github.com wrote:

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.


Reply to this email directly or view it on GitHub.

@MarkDK - sorry - thought it was @stefankroes asking me the question.

MarkDK commented May 21, 2014

I'm a big tree/ancestry model user. Love what I've just discovered in the ancestry gem.

On 21 May 2014, at 20:00, Tim Chambers notifications@github.com wrote:

@MarkDK - sorry - thought it was @stefankroes asking me the question.


Reply to this email directly or view it on GitHub.

@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!

djberg96 commented Jan 18, 2017 edited

@tjchambers I was just looking for this feature. Any chance you could release it as a separate gem? ancestry_plus perhaps?

@djberg96 you are free to use my fork. Would like to hear your reasoning for a separate GEM given this is @stefankroes code with some "tweaks".

@tjchambers The main reason would be for projects that want to use your code as a dependency. It's easier to manage a gem within a gemspec/Gemfile than it is to point to a fork. Also, having your own gem means that I don't have to rely on your fork existing forever and/or github.com issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment