Relational mapping in RedBeanPHP is done using lists. For instance let's say we have a village and buildings. The buildings belong to the village, so the village 'owns' buildings. This is a one-to-many relationship because we have ONE village that has MANY buildings. In RedBeanPHP this is an own-list:
$village = R::dispense('village');
list($mill,$tavern) = R::dispense('building',2);
//replaces entire list
$village->ownBuilding = array($mill,$tavern);
R::store($village);
Now, the mill and tavern buildings belong to the village. In the database, RedBeanPHP will add a village_id field to the building table, pointing to the village record the building belongs to.
An own-list always bears the name of the type of beans it contains: ownBuilding only contains beans of type 'building', ownPage contains pages etc..
Adding the same building to another village causes the other village to steal the building! This is because the own-list contains only beans exclusively owned by the owner bean. That makes sense because it's an one-to-many relationship, not a many-to-many relationship.
Once stored, lists will be retrieved the moment you access the property (we call this lazy loading). To retrieve all the buildings in a village:
$village = R::load('village',$id);
$buildings = $village->ownBuilding;
To add a building to an existing own-list use:
//add a building
$village->ownBuilding[] = $building;
to replace all buildings in an own-list:
$village->ownBuilding = array( $building1, $building2 );
The buildings are keyed by their database IDs. So to replace a bean:
$village->ownBuilding[$id] = $house;
To delete a building from the list use unset()...
unset($village->ownBuilding[$someID]);
R::store($village);
Note that you cannot empty a list by unsetting it. Use:
$village->ownBuilding = array();
for that. This is because in the context of a list, unsetting means 'clear to reload'.
By default if you remove a bean from a list the connection will be broken (in case of a shared list the intermediate bean is also deleted) but the referenced bean will remain in the database. If you want RedBeanPHP to remove beans for you that have been removed from lists use:
R::dependencies(array('page'=>array('book','magazine')));
//will now also destroy the page.
unset($book->ownPage[$id]);
Note that you can only call this method once. If you call it for a second time it will replace the previous dependency list. Also, you can't use this method to remove the constraints in the database; this have to be done manually.
From RedBeanPHP 3.2 on making beans dependent on other beans will also add an ON CASCADE DELETE trigger on the corresponding foreign key.
Imagine you have a shelf with books. To obtain the books from the shelf you can use the own-list: $shelf->ownBook. Sometimes you want to modify this list; ordering the books in the list for instance. To do this you can add a little SQL like this:
$books = $shelf->with(' ORDER BY title ASC ')->ownBook;
To limit the number of books in the list:
$books = $shelf->with(' LIMIT 10 ')->ownBook;
To filter:
$books = $shop->withCondition(' price < 50 ')->ownBook;
A with() or withCondition() method triggers a reload of the list, even if the query has not changed.
withCondition() and with() have been added in version 3.3
From 3.4 on you can also bind parameters in these SQL snippets:
$books = $shop->withCondition(' price < ? ',
array($price))->ownBook;
The own-list is the RedBeanPHP implementation of one-to-many relations. Many-to-one relations are implemented using so-called parent beans.
RedBeanPHP Easy ORM for PHP © 2024 Gabor de Mooij and the RedBeanPHP community - Licensed New BSD/GPLv2