0
votes

Problem Synopsis: (CakePHP v2.4.2) When I use saveAssociated (or saveAll, same result) for input for a new record with a hasMany/belongsTo relationship with multiple child elements, only the last child element gets saved because it INSERTs the first element, but then executes UPDATES for subsequent elements. I've used saveAssociated for very similar purposes in this same application and had no problem with it, so I'm baffled. Queries on all these work just fine, i.e., I get the multiple children associated with each parent.

Models synopsis:

class Site extends AppModel {
    // sites columns:  id (primary key), bunch of others
    public $hasMany = array(
        'SiteUser' => array(
            'className' => 'SiteUser',
            'foreignKey' => 'id', // Yes, I would have preferred 'site_id', lost battle
            'dependent' => true
        )
    );
}
class SiteUser extends AppModel {
    // site_users columns:  rowid(PK), id (FK to sites), name
    public $belongsTo = array(
        'className' => 'Site',
        'foreignKey' => 'id'
    );
}

Equivalent request data (processed from form):

$site_data = array(
    'Site' => array('field1' => 'value1', 'field2' => 'value2' ),
    'SiteUser' => array(
         array('name' => 'Jane Doe'),
         array('name' => 'John Doe'),
         array('name' => 'Moe Money')
    )

);

In the controller:

unset($this->Site->SiteUser->validate['id']);
$saved_site = $this->Site->saveAssociated($site_data);

Results: All of the Site data gets saved as expected. Only the last SiteUser element (Moe Money in the example) is saved. This is the same regardless of the number of elements in SiteUser, i.e., only the last element gets saved.

SQL Log: It performs an

INSERT INTO site_users (`name`, `id`) VALUES ('Jane Doe', 1) 

but then executes

UPDATE site_users SET 'name' = 'John Doe', 'id' = 1 WHERE site_users = 1
UPDATE site_users SET 'name' = 'Moe Money', 'id' = 1 WHERE site_users = 1

This obviously leaves the very last element as the one to get saved, the others are over-written by updates.

Thanks for any pointers in advance.

1

1 Answers

0
votes

You better stick to the conventions, id as the foreign key? No, really, don't do that!

In any case you must tell your SiteUser model about the primary key column name in case it doesn't follow the conventions. See Cookbook > Models > Model Attributes > primaryKey

class SiteUser extends AppModel {

    public $primarykey = 'rowid';

    // ...

}

And while setting this to rowid will most likely fix the problem, I'd again advise to stick to the naming conventions instead!