#6245: HABTM primaryKey identified in one direction only, bad DELETE queries
---------------------------------+------------------------------------------
    Reporter:  cuppett           |         Owner:           
        Type:  Test Case         |        Status:  reopened 
    Priority:  High              |     Milestone:  1.2.x.x  
   Component:  General           |       Version:  1.2 Final
    Severity:  Major             |    Resolution:           
    Keywords:  HABTM primaryKey  |   Php_version:  PHP 5    
Cake_version:  1.2.2.8120        |  
---------------------------------+------------------------------------------
Comment (by cuppett):

 Currently:[[BR]]
 [[BR]]
 CakePHP 1.2.3[[BR]]
 PHP 5.2.9[[BR]]
 Postgres 8.3.7[[BR]]
 WinXP[[BR]]
 Apache 2.2.x[[BR]]
 [[BR]]
 I have a tentative fix for this; however, I'm having lots of trouble
 trying to get the test suite installed and running.  Can somebody take
 this patch and run it through?  I'm getting good queries in my environment
 now for HABTM in both directions within the same controller.
 [[BR]]
 [[BR]]
 The problem was that if you were using both Models in your uses() and
 potentially executing HABTM updates from either side in the same
 Controller, you would get one designation of the column to be used for the
 preceeding DELETE queries in a ->save().  Taking mostly defaults for the
 HABTM relationship would first get a 'joinTable' calculation of abc order
 of the Model tables and then a 'with' calculation of a derivative of
 'joinTable'.  Later on, in __generateAssociation() it would set primaryKey
 to one of the two columns.  Because this new dynamic class gets registered
 in the ClassRegistry, when the next model is loaded, it would pick up all
 the same stuff, including the $primaryKey designator.
 [[BR]][[BR]]
 My fix changes the code slightly to reduce an ordering dependency on
 __associationKeys wrt to the foreach loop and the calculation of
 'joinTable' prior to 'with'.  It also calculates the default value of
 'with' for each side of the HABTM without ordering the tables.  So in
 Posts, the name will be PostsTag and in Tags it will be TagsPost.  This
 gets the deletes right no matter which is done and no matter what order
 they appear in the uses() array.  Also, it has a minor optimization to to
 avoid multiple rows returned when getting the idList for the DELETE.
 [[BR]][[BR]]
 The patch is on TheChaw under Cuppett's Fork as 6a07...745e:
 [[BR]][[BR]]
 
http://thechaw.com/forks/cuppett/cakephp/commits/view/6a07a5bc8b00235a19f59b5a43e004b39fd5745e
 [[BR]][[BR]]
 {{{
 diff --git a/cake/libs/model/datasources/dbo_source.php
 b/cake/libs/model/datasources/dbo_source.php
 index f2aa64e..29c348e 100644
 --- a/cake/libs/model/datasources/dbo_source.php
 +++ b/cake/libs/model/datasources/dbo_source.php
 @@ -1472,7 +1472,7 @@ class DboSource extends DataSource {
                         $conditions =
 $this->conditions($this->defaultConditions($model, $conditions, false),
 true, true, $model);
                 } else {
                         $idList = $model->find('all', array(
 -                               'fields' =>
 "{$model->alias}.{$model->primaryKey}",
 +                               'fields' => "DISTINCT
 {$model->alias}.{$model->primaryKey}",
                                 'conditions' => $conditions
                         ));

 @@ -2447,4 +2447,4 @@ class DboSource extends DataSource {
                 return 'string';
         }
  }
 -?>
 \ No newline at end of file
 +?>
 diff --git a/cake/libs/model/model.php b/cake/libs/model/model.php
 index ae19e51..d8662b1 100644
 --- a/cake/libs/model/model.php
 +++ b/cake/libs/model/model.php
 @@ -674,7 +674,7 @@ class Model extends Overloadable {
                                                 break;

                                                 case 'with':
 -                                                       $data =
 
Inflector::camelize(Inflector::singularize($this->{$type}[$assocKey]['joinTable']));
 +                                                       $data =
 Inflector::camelize(Inflector::singularize($this->table . "_" .
 $this->{$class}->table));
                                                         $dynamicWith =
 true;
                                                 break;

 @@ -2871,4 +2871,4 @@ class Model extends Overloadable {
  if (!defined('CAKEPHP_UNIT_TEST_EXECUTION')) {
         Overloadable::overload('Model');
  }
 -?>
 \ No newline at end of file
 +?>

 }}}

-- 
Ticket URL: <https://trac.cakephp.org/ticket/6245#comment:7>
CakePHP : The Rapid Development Framework for PHP <https://trac.cakephp.org/>
Cake is a rapid development framework for PHP which uses commonly known design 
patterns like ActiveRecord, Association Data Mapping, Front Controller and MVC. 
Our primary goal is to provide a structured framework that enables PHP users at 
all levels to rapidly develop robust web applications, without any loss to 
flexibility.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"tickets cakephp" group.
To post to this group, send email to tickets-cakephp@googlegroups.com
To unsubscribe from this group, send email to 
tickets-cakephp+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/tickets-cakephp?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to