Reputation: 6394
I am trying to use the find
function to query the database table by id. The table has 4 primary keys (3 foreign keys).
This is the code of the table data gateway:
class Application_Model_DbTable_Assigneduser extends Zend_Db_Table_Abstract
{
protected $_name = 'assigneduser';
}
This is the code of the Mapper:
public function find($id)
{
$result = $this->getDbTable()->find($id);
if(count($result) == 0)
return;
$row=$result->current();
$assignedUser = new Application_Model_AssignedUser();
$assignedUser->setId($row->id)
->setIdProject($row->id_project)
->setIdUser($row->id_user)
->setIdTask($row->id_task);
}
The code I use to instantiate the mapper and where I use the method find
:
public function indexAction()
{
echo "<xmp>";
$user=new Application_Model_AssignedUserMapper();
print_r($user->find(3));
echo '</xmp>';
}
I used the print_r
and xmp
tag to have a good look at what the code returns. The exception message I get is:
Message: Too few columns for the primary key
I have no idea what to do to fix it. Any idea? Thank you!
Upvotes: 1
Views: 3759
Reputation: 993
I just had the same problem. On ZF version 1.11.11, it is just as RockyFord said, you just have to map in the DbTable class an array of columns that are the primary key like this:
class AssignedUser extends Zend_Db_Table_Abstract
{
protected $_name = 'assigned_user';
protected $_primary = array('user_id','project_id','task_id');
}
But when you want to find this record, you can't just find by one of the primary keys, not even pass an array with them (that's what I was doing), the find method is waiting a unlimited number of arguments as the primary key's values (following the same order you declared), like this:
$assignedUserTable = new AssignedUser();
$rowset = $assignedUserTable->find( $userId, $projectId, $taskId );
$row = $rowset->current();
Upvotes: 0
Reputation: 8519
Ok find() will return rows by Primary Key and only primary key if you need to pass a compound primary key it must be as an array.
Here is the doc block for find():
/**
* Fetches rows by primary key. The argument specifies one or more primary
* key value(s). To find multiple rows by primary key, the argument must
* be an array.
*
* This method accepts a variable number of arguments. If the table has a
* multi-column primary key, the number of arguments must be the same as
* the number of columns in the primary key. To find multiple rows in a
* table with a multi-column primary key, each argument must be an array
* with the same number of elements.
*
* The find() method always returns a Rowset object, even if only one row
* was found.
*
* @param mixed $key The value(s) of the primary keys.
* @return Zend_Db_Table_Rowset_Abstract Row(s) matching the criteria.
* @throws Zend_Db_Table_Exception
*/
To fix:
class Application_Model_DbTable_Assigneduser extends Zend_Db_Table_Abstract
{
protected $_name = 'assigneduser';
protected $_primary = array('column','column'...); //This is not strictly required but may help.
}
public function indexAction()
{
$user=new Application_Model_AssignedUserMapper();
Zend_Debug::dump($user->find(array(3,,,)), 'User');//outputs formatted var_dump with optional label as second arg.
}
Now to make this easy:
public function find($id)
{
$select = $this->getDbTable->select();
$select->where('id = ?', $id);
$result = $this->getDbTable()->fetchRow($select);//will return only one row, if you need more use fetchAll()
if(is_null($result)) //fetchRow() returns NULL if no rows found.
return;
$row=$result;
$assignedUser = new Application_Model_AssignedUser();
$assignedUser->setId($row->id)
->setIdProject($row->id_project)
->setIdUser($row->id_user)
->setIdTask($row->id_task);
}
Using fetchRow() you can query against any column in the row, but it will only return one row. If you need a rowset returned you can use fetchAll() with the same query options and you will get a rowset.
Hope this helps.
Upvotes: 1