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 ключ (в моём случае он составной).
Похоже на баг. Будем благодарны если иностаранноговорящие коллеги сообщат разработчикам.