kwerle-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org
2009-Sep-30 04:26 UTC
Populating parent relationships automagically
I would like to populate parent relationships when I load children objects. I have a relatively complex object graph. Something like: Thing <1-*> Components <1-*> Assembly <*-*> Parts The notion is that we allow a Thing to be designed with ''construction issues'', but can''t be ''manufactured'' until it doesn''t have any issues. There can be issues at any level. A Thing can have too many components. A component can have the wrong kinds of Assemblies. So far, so good. The problem comes in where there are complex grouping rules. There are grouping rules for Parts that depend on how many of the same Part exist within the entire Thing, for example. When I fetch, I do something like Thing.find(some_id, :includes => {:components => {:assmeblies => :parts}}) and that works fine. But when I want to display some of the errors associated with a Part, I have to reach back up to Thing to find some of the issues. part.assembly.component.thing will return a different object for every part. So I''m interested in a plugin or some code that will populate the parent relationships when the children objects are loaded. Then I''ll be able to traverse relationships up and down without proliferating objects. Or other architectural suggestions.
On Sep 30, 11:26 am, "kwe...-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org" <kurt.we...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I would like to populate parent relationships when I load children > objects. I have a relatively complex object graph. Something like: > Thing <1-*> Components <1-*> Assembly <*-*> Parts >> > part.assembly.component.thing will return a different object for every > part. >Most likely you are maintaining a many to many relationship table between <% :parts %> and <% :assemblies %>. That means a single Part can be associated with multiple Assembly. As you wrote: <% part.assembly.component.thing %> In the above call <% part.assemble %> will return array of assembles and you can not call <% .component %> on that array. You need to distinguish between the Assemblies of a single Part to reach up to its'' Thing. Would you please give some of your sample associations and the scenario where you need to call <% part.assembly.component.thing %>? Hope i can provide something more specific. Thank you
On Sep 29, 10:48 pm, Samiron <samironp...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Sep 30, 11:26 am, "kwe...-e+AXbWqSrlAAvxtiuMwx3w@public.gmane.org" <kurt.we...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > I would like to populate parent relationships when I load children > > objects. I have a relatively complex object graph. Something like: > > Thing <1-*> Components <1-*> Assembly <*-*> Parts > > > part.assembly.component.thing will return a different object for every > > part. > > Most likely you are maintaining a many to many relationship table > between <% :parts %> and <% :assemblies %>. That means a single Part > can be associated with multiple Assembly. > > As you wrote: <% part.assembly.component.thing %> > > In the above call <% part.assemble %> will return array of assembles > and you can not call <% .component %> on that array.You''re right, I botched my analogy. It is assembly that is reaching up.> Would you please give some of your sample associations and the > scenario where you need to call <% part.assembly.component.thing %>? > Hope i can provide something more specific.Supposing that def Thing#assemblies components.map(&:assemblies).flatten.uniq end def Assembly#manufacturing_issues issues = [] ... if component.thing.assemblies.map(&:type).include?(conflicting_type) issues << "Can not have a #{conflicting_type} in the same thing." end ... issues end Here we have an assembly reaching up to its Thing to find out if any of its peers is of conflicting type. Keep in mind that I want this issue to be displayed with the Assembly - so this is where I put the logic. Also it seems reasonable to keep it here since it is knowledge of the Assembly types that defines whether or not it conflicts. Since parent relationships are not populated, we''re going to get a different Thing - which means that Thing is going to need to load *all* its assemblies just to see if there is one that conflicts. I''d like to be able to traverse the object graph and get to the Thing that caused this Assembly to load - that way I would be using the same objects; no additional loads needed..