[Solar-svn] Revision 3194
pmjones at solarphp.com
pmjones at solarphp.com
Mon Jun 2 19:36:12 CDT 2008
Solar_Sql_Model_Related, (BelongsTo|HasOne|HasMany)
---------------------------------------------------
Add inflection logic to set default values for foreign keys, etc.
* [ADD] Method _fixForeignKey() sets the 'foreign_key' value based on the related name.
* [ADD] Method _setForeignClass() sets the $foreign_class property based on the related name.
* [ADD] Method dump() to help with debugging.
Modified: trunk/Solar/Sql/Model/Related/BelongsTo.php
===================================================================
--- trunk/Solar/Sql/Model/Related/BelongsTo.php 2008-06-02 02:16:27 UTC (rev 3193)
+++ trunk/Solar/Sql/Model/Related/BelongsTo.php 2008-06-03 00:36:12 UTC (rev 3194)
@@ -54,6 +54,17 @@
$this->type = 'belongs_to';
}
+ protected function _fixForeignKey(&$opts)
+ {
+ $prefix = $this->_inflect->toSingular(
+ $this->_foreign_model->table_name
+ );
+
+ $column = $this->_foreign_model->primary_col;
+
+ $opts['foreign_key'] = "{$prefix}_{$column}";
+ }
+
/**
*
* Fixes the related column names in the user-defined options **in place**.
Modified: trunk/Solar/Sql/Model/Related/HasMany.php
===================================================================
--- trunk/Solar/Sql/Model/Related/HasMany.php 2008-06-02 02:16:27 UTC (rev 3193)
+++ trunk/Solar/Sql/Model/Related/HasMany.php 2008-06-03 00:36:12 UTC (rev 3194)
@@ -31,6 +31,15 @@
*/
protected $_fetch_object = 'collection';
+ // unlike has-one and belongs-to, assume the related name is plural
+ protected function _setForeignClass($opts)
+ {
+ if (empty($opts['foreign_class'])) {
+ $opts['foreign_class'] = $opts['name'];
+ }
+ parent::_setForeignClass($opts);
+ }
+
/**
*
* When the native model is doing a select and an eager-join is requested
@@ -65,13 +74,13 @@
$table = "{$this->foreign_table} AS {$this->foreign_alias}";
$where = "{$this->through_alias}.{$this->through_foreign_col} = "
. "{$this->foreign_alias}.{$this->foreign_col}";
-
+
$select->leftJoin($table, $where);
-
+
// make the rows distinct, so we only get one row regardless of
// the number of related rows (since we're not selecting cols).
$select->distinct(true);
-
+
// honor foreign inheritance
if ($this->foreign_inherit_col) {
$select->where(
@@ -148,6 +157,23 @@
$this->type = 'has_many';
}
+ protected function _fixForeignKey(&$opts)
+ {
+ if (empty($opts['through'])) {
+ // has-many, not through anything
+ $prefix = $this->_inflect->toSingular(
+ $this->_native_model->table_name
+ );
+
+ $column = $this->_native_model->primary_col;
+
+ $opts['foreign_key'] = "{$prefix}_{$column}";
+ } else {
+ // has-many through
+ $opts['foreign_key'] = $this->_foreign_model->primary_col;
+ }
+ }
+
/**
*
* Fixes the related column names in the user-defined options **in place**.
@@ -262,6 +288,7 @@
empty($opts['through_foreign_col']) &&
! empty($opts['through_key'])) {
// pre-define through_foreign_col
+ $this->through_key = $opts['through_key'];
$opts['through_foreign_col'] = $opts['through_key'];
}
Modified: trunk/Solar/Sql/Model/Related/HasOne.php
===================================================================
--- trunk/Solar/Sql/Model/Related/HasOne.php 2008-06-02 02:16:27 UTC (rev 3193)
+++ trunk/Solar/Sql/Model/Related/HasOne.php 2008-06-03 00:36:12 UTC (rev 3194)
@@ -54,6 +54,17 @@
$this->type = 'has_one';
}
+ protected function _fixForeignKey(&$opts)
+ {
+ $prefix = $this->_inflect->toSingular(
+ $this->_native_model->table_name
+ );
+
+ $column = $this->_native_model->primary_col;
+
+ $opts['foreign_key'] = "{$prefix}_{$column}";
+ }
+
/**
*
* Fixes the related column names in the user-defined options **in place**.
Modified: trunk/Solar/Sql/Model/Related.php
===================================================================
--- trunk/Solar/Sql/Model/Related.php 2008-06-02 02:16:27 UTC (rev 3193)
+++ trunk/Solar/Sql/Model/Related.php 2008-06-03 00:36:12 UTC (rev 3194)
@@ -314,6 +314,14 @@
*/
protected $_fetch_object = 'record';
+ protected $_inflect;
+
+ public function __construct($config = null)
+ {
+ parent::__construct($config);
+ $this->_inflect = Solar_Registry::get('inflect');
+ }
+
/**
*
* Sets the native (origin) model instance.
@@ -375,6 +383,7 @@
{
$this->name = $opts['name'];
$this->_setType();
+ $this->_setForeignClass($opts);
$this->_setForeignModel($opts);
$this->_setCols($opts);
$this->_setSelect($opts);
@@ -382,16 +391,37 @@
// if the user has specified *neither* a foreign_col *nor* a native_col,
// but *has* specified a foreign_key, use the foreign_key to define
// the foreign_col or native col (depending on relation type).
- if (empty($opts['native_col']) &&
- empty($opts['foreign_col']) &&
- ! empty($opts['foreign_key'])) {
- // redefine based on the "virtual" foreign_key value
+ if (empty($opts['native_col']) && empty($opts['foreign_col'])) {
+
+ // if a "virtual" foreign_key value is not set, define one
+ if (empty($opts['foreign_key'])) {
+ $this->_fixForeignKey($opts);
+ }
+
+ // retaing the foreign key
+ $this->foreign_key = $opts['foreign_key'];
+
+ // now set the related column based on the foreign_key value
$this->_fixRelatedCol($opts);
}
$this->_setRelated($opts);
}
+ public function dump($var = null, $label = null)
+ {
+ if ($var) {
+ return parent::dump($var, $label);
+ }
+
+ $clone = clone($this);
+ unset($clone->_config);
+ unset($clone->_native_model);
+ unset($clone->_foreign_model);
+ unset($clone->_inflect);
+ return parent::dump($clone, $label);
+ }
+
/**
*
* Creates a new selection object for fetching records from this relation.
@@ -663,6 +693,22 @@
$select->multiWhere($this->where);
}
+ // make sure we have at least a base class name. assume the related name
+ // is singular.
+ protected function _setForeignClass($opts)
+ {
+ if (empty($opts['foreign_class'])) {
+ // no class given. change 'foo_bar' to 'FooBar' ...
+ $class = $this->_inflect->underToStudly($opts['name']);
+ // ... then use the plural form of the name.
+ $this->foreign_class = $this->_inflect->toPlural($class);
+ } else {
+ $this->foreign_class = $opts['foreign_class'];
+ }
+ }
+
+ abstract protected function _fixForeignKey(&$opts);
+
/**
*
* Sets the foreign model instance based on user-defined relationship
@@ -675,13 +721,6 @@
*/
protected function _setForeignModel($opts)
{
- // make sure we have at least a base class name
- if (empty($opts['foreign_class'])) {
- $this->foreign_class = $opts['name'];
- } else {
- $this->foreign_class = $opts['foreign_class'];
- }
-
// can we load a related model class from the hierarchy stack?
$class = $this->_native_model->stack->load($this->foreign_class, false);
@@ -741,7 +780,6 @@
$this->foreign_alias = $opts['name'];
}
-
/**
*
* Sets the foreign columns to be selected based on user-defined
More information about the Solar-svn
mailing list