3 * TActiveRecordBelongsTo class file.
5 * @author Wei Zhuo <weizhuo[at]gmail[dot]com>
6 * @link https://github.com/pradosoft/prado
7 * @copyright Copyright © 2005-2016 The PRADO Group
8 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
10 * @package System.Data.ActiveRecord.Relations
14 * Loads base active record relationship class.
16 Prado::using('System.Data.ActiveRecord.Relations.TActiveRecordRelation');
19 * Implements the foreign key relationship (TActiveRecord::BELONGS_TO) between
20 * the source objects and the related foreign object. Consider the
21 * <b>entity</b> relationship between a Team and a Player.
24 * | Team | 1 <----- * | Player |
27 * Where one team may have 0 or more players and each player belongs to only
28 * one team. We may model Team-Player <b>object</b> relationship as active record as follows.
30 * class TeamRecord extends TActiveRecord
32 * // see TActiveRecordHasMany for detailed definition.
34 * class PlayerRecord extends TActiveRecord
36 * const TABLE='player';
37 * public $player_id; //primary key
38 * public $team_name; //foreign key player.team_name <-> team.name
40 * public $team; //foreign object TeamRecord
42 * public static $RELATIONS = array
44 * 'team' => array(self::BELONGS_TO, 'TeamRecord')
47 * public static function finder($className=__CLASS__)
49 * return parent::finder($className);
53 * The static <tt>$RELATIONS</tt> property of PlayerRecord defines that the
54 * property <tt>$team</tt> belongs to a <tt>TeamRecord</tt>.
56 * The team object may be fetched as follows.
58 * $players = PlayerRecord::finder()->with_team()->findAll();
60 * The method <tt>with_xxx()</tt> (where <tt>xxx</tt> is the relationship property
61 * name, in this case, <tt>team</tt>) fetchs the corresponding TeamRecords using
62 * a second query (not by using a join). The <tt>with_xxx()</tt> accepts the same
63 * arguments as other finder methods of TActiveRecord, e.g.
64 * <tt>with_team('location = ?', 'Madrid')</tt>.
66 * @author Wei Zhuo <weizho[at]gmail[dot]com>
68 * @package System.Data.ActiveRecord.Relations
71 class TActiveRecordBelongsTo extends TActiveRecordRelation
74 * Get the foreign key index values from the results and make calls to the
75 * database to find the corresponding foreign objects.
76 * @param array original results.
78 protected function collectForeignObjects(&$results)
80 $fkeys = $this->getRelationForeignKeys();
82 $properties = array_keys($fkeys);
83 $fields = array_values($fkeys);
84 $indexValues = $this->getIndexValues($properties, $results);
85 $fkObjects = $this->findForeignObjects($fields, $indexValues);
86 $this->populateResult($results,$properties,$fkObjects,$fields);
90 * @return array foreign key field names as key and object properties as value.
93 public function getRelationForeignKeys()
95 $fkObject = $this->getContext()->getForeignRecordFinder();
96 return $this->findForeignKeys($this->getSourceRecord(),$fkObject);
100 * Sets the foreign objects to the given property on the source object.
101 * @param TActiveRecord source object.
102 * @param array foreign objects.
104 protected function setObjectProperty($source, $properties, &$collections)
106 $hash = $this->getObjectHash($source, $properties);
107 $prop = $this->getContext()->getProperty();
108 if(isset($collections[$hash]) && count($collections[$hash]) > 0)
110 if(count($collections[$hash]) > 1)
111 throw new TActiveRecordException('ar_belongs_to_multiple_result');
112 $source->$prop=$collections[$hash][0];
119 * Updates the source object first.
120 * @return boolean true if all update are success (including if no update was required), false otherwise .
122 public function updateAssociatedRecords()
124 $obj = $this->getContext()->getSourceRecord();
125 $fkObject = $obj->getColumnValue($this->getContext()->getProperty());
129 $source = $this->getSourceRecord();
130 $fkeys = $this->findForeignKeys($source, $fkObject);
131 foreach($fkeys as $srcKey => $fKey)
132 $source->setColumnValue($srcKey, $fkObject->getColumnValue($fKey));