gabordemooij / redbean

ORM layer that creates models, config and database on the fly
https://www.redbeanphp.com
2.31k stars 279 forks source link

many-to-many self-referential problem #292

Closed alrik11es closed 11 years ago

alrik11es commented 11 years ago

The docs doesn't make it really clear how this must be achieved. It would be awesome if you could explain this a little bit more with an example or something.

many-to-many self-referential $category->sharedCategory = $category

I've tried what you've said in the cheatsheet but that doesn't make much sense at all.

I'm using the 3.4.4 version.

I've been trying to self-reference geographical locations. And I've tried with:

$geounit->sharedGeounit[] = $parent_geounit; This gets something like the result I need but when I access the $geounit->sharedGeounit then it gets all beans where the N:M table has the id of the actual geounit no matter if in geounit_id or geounit2_id field.

$geounit->sharedGeounit = $parent_geounit; This other by the way acts like as one-to-many relationship. That it's not the case.

I know that it's probably my fault but for me could be handsome some fresh air with your answer :)

gabordemooij commented 11 years ago

What are you trying to accomplish? A tree with multiple parents?

alrik11es commented 11 years ago

Yes it's an inverted tree with multiple locations for each location could have multiple parents. I can draw an example if you need it. The thing is that I can achieve the same result on the old fashioned SQL queries way but if I can do it directly with the RB library would be awesome.

gabordemooij commented 11 years ago

Might be a missing concept? What about combining a tree and an N-M relation?

//regions are tree
$regions = R::dispense('region', 3);
$regions[0]->ownRegion = array($regions[1], $regions[2]);

//each region has several locations
$locations = R::dispense('location', 4);
$regions[0]->sharedLocation[] = $locations[0];
$regions[1]->sharedLocation = array($locations[1], $locations[2]);
$regions[2]->sharedLocation[] = $locations[3];
R::storeAll($regions);

$x = $regions[0]->fresh(); //reload
R::preload($x, 'ownRegion|region,*.sharedLocation|location');
print_r(R::exportAll($x));

This might solve the problem. You can't use self-referential N-M relations for this because RedBeanPHP explicitly runs an extra query to add the 'other half' of the mutual relations for you (useful for concepts like friends).

If you post this at our forum, other people might post more suggestions: https://groups.google.com/forum/?fromgroups#!forum/redbeanorm

alrik11es commented 11 years ago

Ok, thanks. I'll try asking on the forum with a better explanation.