[Решено] Проблема с HAS MANY

Общие вопросы по использованию фреймворка. Если не знаете как что-то сделать и это про Yii, вам сюда.
Ответить
byteasdf
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

[Решено] Проблема с HAS MANY

Сообщение byteasdf »

Есть 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';
    }
}
?>
Получаю значения в контроллере

Код: Выделить всё

$criteria = new CDbCriteria();
$criteria->addCondition('`org_id` = :id');
$criteria->params[':id'] = $model->id;
$criteria->with = array('phones');
$persons = Person::model()->findAll($criteria);
foreach ($persons as $person)
{
    echo count($person->phones),'<br>';
    echo $person->phones[0]->id,'<br>';
}
 
И вот тут начинаются странности,
1) Для всех людей оно показывает, что count($person->phones) = 1, хотя в базе явно не так
2)Для всех людей оно показывает одинаковое $person->phones[0]->id(что меня вообще вводит в ступор)
Версия Yii 1.1.4, в другой модели есть HAS_MANY, и он нормально работает.
Подскажите, куда копать тут?
Последний раз редактировалось byteasdf 2010.09.15, 11:35, всего редактировалось 1 раз.

byteasdf
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

Re: Дополнения к проблеме с HAS MANY

Сообщение byteasdf »

Пара выдержек из 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 |
+----+---------+
Но в то же время

Код: Выделить всё

$model = Person::model()->findByPk('689');
echo count($model->phones);
echo $model->phones[0]->id;
 
выводит что телефон один, и его идентификатор 69.

Dr0ID
Сообщения: 27
Зарегистрирован: 2010.04.04, 20:02
Откуда: Новосибирск
Контактная информация:

Re: Проблема с HAS MANY

Сообщение Dr0ID »

Я бы так написал:

Код: Выделить всё

$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>";
    }
}
Никогда таких проблем не было.

byteasdf
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

Re: По поводу форматирования кода.

Сообщение byteasdf »

Dr0ID писал(а):Я бы так написал:

Код: Выделить всё

$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>";
    }
}
 
В данном случае результаты поиска должны зависеть не только от org_id, просто перед тем, как постить сюда я сначала убрал все лишнее, чтобы исключить проблему там. А когда условий поиска удобнее, имхо, использовать CDbCriteria.
И ошибка соответственно не тут, вывод этого кода такой:
689
phone: 69
740
phone: 69
741
phone: 69
То есть для всех пользователей выводит телефон с id=69. В то время, как у того телефона user_id=689.

Dr0ID
Сообщения: 27
Зарегистрирован: 2010.04.04, 20:02
Откуда: Новосибирск
Контактная информация:

Re: Проблема с HAS MANY

Сообщение Dr0ID »

Включите CProfileLogRoute и посмотрите, что за запрос там получается.

byteasdf
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

Re: Проблема с HAS MANY

Сообщение byteasdf »

Dr0ID писал(а):Включите CProfileLogRoute и посмотрите, что за запрос там получается.
При выполнении кода

Код: Выделить всё

$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
Сообщения: 99
Зарегистрирован: 2010.09.15, 09:01

Re: Решено

Сообщение byteasdf »

Вся проблема заключалась в том, что в таблице, с которой была связанна модель PhonePerson не было primary_key. А id был объявлен как простой key.
Всем спасибо.

Ответить