byteasdf
(Byteasdf)
September 15, 2010, 7:07am
1
Есть 2 модели, модель людей(Person) и модель их телефонов(PhonePerson).
<?php
class Person extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'addressBook';
}
public function relations()
{
return array(
'phones'=>array(self::HAS_MANY,'PhonePerson','user_id'),
);
}
}
?>
<?php
class PhonePerson extends CActiveRecord
{
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'phone_numbers';
}
}
?>
И есть данный код в контроллере
$model = Person::model()->findByPk('689');
echo count($model->phones);
который говорит, что количество телефонов равно 1.
хотя MySQL, если его спрашивать, выдает другое
mysql> select count(id) from addressBook where id = 689;
±----------+
| count(id) |
±----------+
| 1 |
±----------+
mysql> select id, user_id from phone_numbers where user_id = 689;
±—±--------+
| id | user_id |
±—±--------+
| 69 | 689 |
| 70 | 689 |
| 80 | 689 |
| 81 | 689 |
±—±--------+
И вторая проблема, которая связанна с этой. При выборке нескольких человек оно у всех выводит один и тот же телефон, наприме код:
$persons = Person::model()->with('phones')->findAll('`org_id` = :id', array('id'=>$model->id));
foreach ($persons as $person){
echo $person->id . "<br>";
foreach ($person->phones AS $phone){
echo "phone: " . $phone->id . "<br>";
}
}
выводит
689
phone: 69
740
phone: 69
741
phone: 69
Версия Yii 1.1.4. В другой модели отношение HAS_MANY работает нормально. Подскажите куда копать?
Mougrim
(Rinat)
September 15, 2010, 8:05am
2
Укажи в конфиге логировать запросы, и посмотри, какие запросы формируются.
Нужно добавить (если нету) в components:
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CWebLogRoute',
'levels' => 'trace, info, profile, warning, error',
'categories'=>'system.db.CDbCommand',
'showInFireBug' => true,
),
array(
'class'=>'CFileLogRoute',
'levels' => 'trace, info, profile, warning, error',
'categories'=>'system.db.CDbCommand',
),
),
),
Где CFileLogRoute - логирование в файл, а CWebLogRoute - логирование в консоль фаербага (если у тебя фаерфокс с плагином Firebug). categories - это что логировать.
P.S. если юзаешь аякс, то CWebLogRoute лучше отключить, т.к. пришедшие данные будут смешаны с данными для консоли фаербага.
Подробнее
byteasdf
(Byteasdf)
September 15, 2010, 8:09am
3
При выполнении кода
$model = Person::model()->with('phones')->findByPk('689');
echo count($model->phones);
в профайлере получается следующий запрос
SELECT t.name1 AS t0_c0, t.name2 AS t0_c1, t.name3 AS t0_c2, t.org_id AS t0_c3, t.position AS t0_c4, t.comments_short AS t0_c5, t.comments AS t0_c6, t.tel_work AS t0_c7, t.tel_home AS t0_c8, t.fax_work AS t0_c9, t.tel_mobile AS t0_c10, t.otdel AS t0_c11, t.address_work AS t0_c12, t.birthday AS t0_c13, t.im AS t0_c14, t.id AS t0_c15, t.tags AS t0_c16, t.email AS t0_c17, phones.id AS t1_c0, phones.ccode AS t1_c1, phones.code AS t1_c2, phones.number AS t1_c3, phones.type AS t1_c4, phones.user_id AS t1_c5 FROM addressBook t LEFT OUTER JOIN phone_numbers phones ON (phones.user_id=t.id) WHERE (t.id=689)
При выполнении этого запроса напрямую в MySQL, тот возвращает 4 строки(по количеству телефонов). count($model->phones) все так-же возвращает 1.
byteasdf
(Byteasdf)
September 15, 2010, 8:37am
4
Решено. Проблема возникла из-за того, что в таблице, за которую отвечает PhonePerson не было primary_key. А поле id было просто key.
Всем спасибо.
Mougrim
(Rinat)
September 15, 2010, 10:03am
5
интересное поведение актив рекорда…
ZhAN
(Zhansoft)
September 17, 2010, 11:22am
6
Столкнулся с аналогичной проблемой.
Лечится если в таблице добавить хотябы один primary или UNIQUE ключ (в моём случае он составной).
Похоже на баг. Будем благодарны если иностаранноговорящие коллеги сообщат разработчикам.