[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