When using Active Record with a View (instead of Table) the primary key is not set in the record after save I ran into a problem when saving a new record.  I have created a test below.  When saving a record using a db table, the record is saved to the db and the primary key id is updated in the record object.  Works as expected.

But if the record is saved to a db view (instead of a table), the record is saved to the db but the primary key id is not updated in the record object.  Not working as expected.

I have a third party table that I am using in a plugin that I am developing (in this example, I am calling this third party table craft_test).  I can't changed the name of the table but have created a view name with "craft_" in order to use all of crafts features.

In my example, I have a custom primary key (Member_ID) that I am using.  The issue still exists if I use the the default primary key of id (by changing the Member_ID column to id in the db, removing the primaryKey() method in the Record declaration, removing Member_ID from defineAttributes in the Record, and rennaming  Member_ID to id in the model defineAttributes).

Does anyone have an idea why the view is not working?  Is there a bug in the craft code?  Or is there a setting that I need to modify?

Accd_TestModel.php

namespace Craft;

class Accd_TestModel extends BaseModel
{

public function defineAttributes()
{
    return array(
        'Member_ID'    =&gt; array(AttributeType::Number),
        'FirstName' =&gt; array(AttributeType::String, 'maxLength' =&gt; 40, 'required' =&gt; true),
    );
}
}


Accd_testRecord.php

class Accd_TestRecord extends BaseRecord
{
/**
 * Gets the database table name
 *
 * @return string
 */
public function getTableName()
{
   // REMOVE COMMENT BELOW USE VIEW INSTEAD OF TABLE
   // return 'test_view'; 
   return 'test';   
}

public function primaryKey()
{
   return 'Member_ID';
}

/**
 * Define columns for our database table
 *
 * @return array
 */
public function defineAttributes()
{
    return array(
        'Member_ID'    =&gt; array(AttributeType::Number, 'column' =&gt; ColumnType::PK),
        'FirstName' =&gt; array(AttributeType::String, 'maxLength' =&gt; 40, 'required' =&gt; true),
    );
}

}


Code: 

    $test_model = new Accd_TestModel();
    $test_model-&gt;setAttribute('FirstName', 'Bill');

    $test_record = new Accd_TestRecord();
    $test_record-&gt;setAttributes($test_model-&gt;getAttributes());
    if ($test_record-&gt;save())
    {
        // update Member_ID on model (for new record)
        $test_model-&gt;setAttribute('Member_ID', $test_record-&gt;Member_ID);


        echo '&lt;br&gt;Model FirstName: '.$test_model-&gt;getAttribute('FirstName');
        echo '&lt;br&gt;Model Member_ID: '.$test_model-&gt;getAttribute('Member_ID');
        echo '&lt;br&gt;Record FirstName: '.$test_record-&gt;getAttribute('FirstName');
        echo '&lt;br&gt;Record Member_ID: '.$test_record-&gt;getAttribute('Member_ID');

    }
    else
    {
        echo 'failure';
    }


Database: 

CREATE TABLE IF NOT EXISTS `craft_test` (
`Member_ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`FirstName` varchar(40) NOT NULL DEFAULT '',
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
`uid` char(36) NOT NULL DEFAULT '0',
PRIMARY KEY (`Member_ID`)
 ) ENGINE=InnoDB  DEFAULT CHARSET=latin1;


Database View:

  CREATE VIEW craft_test_view AS SELECT * FROM craft_test


Output to screen when using view:

Model FirstName: Bill
Model Member_ID: 
Record FirstName: Bill
Record Member_ID: 


Output to screen when using table:

Model FirstName: Bill
Model Member_ID: 7
Record FirstName: Bill
Record Member_ID: 7
This should do what you're looking for:

if ($test_record-&gt;save()) 
{
    // update Member_ID on model (for new record)
    $test_model-&gt;setAttribute('Member_ID', craft()-&gt;db-&gt;getLastInsertId());

    ...
}