gabordemooij / redbean

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

Possible to get data back when using Extended Associations? #179

Closed ghost closed 12 years ago

ghost commented 12 years ago

If I have a many-to-many relationship and I want to store some extra data with the many-to-many relationship (link), I can do:

$x = R::dispense('x');
$x->name = 'test';
R::store($x);

$y = R::dispense('y');
$y->name = 'test';
R::store($y);

R::associate($x, $y, array('leader' => 1));

This results in 3 tables:

x
=======
id
name

y
=======
id
name

x_y
=======
id
x_id
y_id
leader

However, it seems to me that ExtAssociationManager is missing a method (extRelated) to get data from the "base bean" back. For example, given the above, there doesn't seem to be a way to get all the Ys that are related to an X along with the base bean for each link in one neat function.

ghost commented 12 years ago

After thinking about this, how about being able to access the link bean from a bean? I am a huge fan of $x->sharedY; //x and y are beans to retrieve all Ys connected to X.

Maybe we could have $x->sharedLinkY to retrieve an array of links with the array keys set to the ids of the Y beans. We can then easily modify the link record as well:

$links = $x->sharedLinkY;
foreach($links as $link){
 $link->leader =0;
 $link->someOtherProp = "property"
 store($link);
}

Perhaps even make $link->x_id and $link->y_id so that people can't easily damage the relationship.

And if we wish to get the link that connects $x to $y:

$xylink = $x->sharedY[0]->sharedLink;
$link->leader = 0;
$link->anotherPropety = 'sometext';

Saving $x would then cascade and save the modified link as well.

gabordemooij commented 12 years ago

Extended Associations are almost never needed. Just treat the association as an intermediate bean.

list($p1,$p2) = R::dispense('person',2);
$p1->name = 'x';
$p2->name = 'y';
$pair = R::dispense('pair');
$pair->person = $p1;
$pair->other = $p2;
$pair->relation = 'friends';

To retrieve:

$pair = R::load('pair',$id);
$p1 = $pair->person;
$p2 = $pair->fetchAs('person')->other;

I regret I ever added extended associations at all. They are a leftover from RedBeanPHP 1.0 when the Association API was far more important and shared[] and own[] lists didnt exist yet.