Reputation: 5133
I have the following code and the when I call my find method it shows me this: "Invalid argument supplied for foreach()" in CActiveFinder at line 784:
$pk=array();
784 foreach($this->_pkAlias as $name=>$alias)
785 {
786 if(isset($row[$alias]))
787 $pk[$name]=$row[$alias];
788 else // no matching related objects
789 return null;
790 }
791 $pk=serialize($pk);
It fails when it reaches this code:
$objCampanie = $modelCampanii->with('stocs')->findAll();
Relations from class Campanii:
* @property Stoc[] $stocs
* @property Vanzari[] $vanzaris
public function relations()
{
return array(
'stocs' => array(self::HAS_MANY, 'Stoc', 'id_campanie'),
'vanzaris' => array(self::HAS_MANY, 'Vanzari', 'id_campanie'),
);
}
Relations from class Stoc
* @property Produse $codProdus
* @property Campanii $idCampanie
* @property Vanzari[] $vanzaris
public function relations()
{
return array(
'codProdus' => array(self::BELONGS_TO, 'Produse', 'cod_produs'),
'idCampanie' => array(self::BELONGS_TO, 'Campanii', 'id_campanie'),
'vanzaris' => array(self::HAS_MANY, 'Vanzari', 'cod_produs'),
);
}
Where is the problem? Why does it not retrieves my code?
Table structure: Campanii:
CREATE TABLE IF NOT EXISTS `campanii` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`nume` varchar(255) NOT NULL,
`data_comanda` date NOT NULL,
`data_scadenta` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
Stoc:
CREATE TABLE IF NOT EXISTS `stoc` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`id_campanie` int(11) NOT NULL,
`cod_produs` varchar(10) NOT NULL,
`cantitate` int(11) NOT NULL,
`pret` double NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `id_campanie` (`id_campanie`),
KEY `cod_produs` (`cod_produs`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
--
-- Constraints for table `stoc`
--
ALTER TABLE `stoc`
ADD CONSTRAINT `stoc_ibfk_1` FOREIGN KEY (`id_campanie`) REFERENCES `campanii` (`id`),
ADD CONSTRAINT `stoc_ibfk_2` FOREIGN KEY (`cod_produs`) REFERENCES `produse` (`cod`);
Upvotes: 3
Views: 2604
Reputation: 1225
I get same error in CActiveFinder(834) after Yii framework update from 1.1.11 to 1.1.14. All was worked before update, all primary keys was setted.
After some struggling I found that errors is gone when I cleaned my YiiCache (I have CDbCache enabled in my config).
TRUNCATE YiiCache
or DELETE FROM YiiCache
Upvotes: 0
Reputation: 5187
The problem was due to a missing primary key in the stoc
table. The reason why follows:
private function populateRecord($query,$row)
{
// determine the primary key value
if(is_string($this->_pkAlias)) // single key
{
if(isset($row[$this->_pkAlias]))
$pk=$row[$this->_pkAlias];
else // no matching related objects
return null;
}
else // is_array, composite key
{
$pk=array();
foreach($this->_pkAlias as $name=>$alias)
{
if(isset($row[$alias]))
$pk[$name]=$row[$alias];
else // no matching related objects
return null;
}
$pk=serialize($pk);
}
...
The above code is from CActiveFinder. As you can see, if the _pkAlias of a table is not a string, then it assumes it's an array, without checking to see if any primary key exists at all.
Therefore, when you call with('stocs')
, CActiveFinder tries to populate the related records (meaning, populateRecord
is called), which tries to figure out the PK as part of its normal process, and so fails due to the lack of a PK.
Ultimately, it is the result of an incorrect assumption in the framework code. It can be worked around (as you found) by simply creating a PK.
You can look at CActiveFinder, starting on line 385, to see how the value of _pkAlias
is set.
https://github.com/yiisoft/yii/blob/1.1.13/framework/db/ar/CActiveFinder.php
Upvotes: 5