nepster-web
@nepster-web

Как прикрутить вложенные реляции одним запросом Yii?

Итак:
Есть таблица игр (games)
Есть таблица заявок на игру (proposal)
Есть таблица ожидающих играть (waiting)

games
public function relations()
    {
        return array(
            'proposal' => array(self::HAS_MANY, 'GameProposalModel', '', 'on'=>'t.game_id=proposal.game_id'),
        );
    }


proposal
public function relations()
    {
        return array(
            'waiting' => array(self::HAS_MANY, 'GameWaitingModel', '', 'on'=>'t.proposal_id=waiting.proposal_id'),
        );
    }



Есть задача сделать такой запрос, что бы получить следующее:
Данные игры
Все заявки со статусом -1
Все пользователи которые в ожидании

Я начал как-то так:
$criteria = new CDbCriteria;
            
            $criteria->select    = 't.game_id, t.game_name, t.alter_name';
            $criteria->condition = "t.game_id=:game_id AND proposal.status=-1";
            $criteria->params    = array(':game_id'=>$game_id);

        
            $criteria->with = array(
                 'proposal' => array('joinType'=>'LEFT JOIN'),
            );
            
        
            $data = GamesModel::model()->find($criteria);


И сразу налетел на 2 косяка:
Если нет ни одной заявки, то возвращается false.
Как можно прикрутить еще вложенную реляцию waiting?


Подскажите пожалуйста.
  • Вопрос задан
  • 4187 просмотров
Пригласить эксперта
Ответы на вопрос 3
Если нет ни одной заявки, то возвращается false

Проверка на наличие false в возвращенном значении.

Как можно прикрутить еще вложенную реляцию waiting

Если я верно понял, что вам требуется, то примерно так:
$criteria->with = array(
    'proposal' => array('joinType'=>'LEFT JOIN'),
    'proposal.waiting',
);
Ответ написан
Комментировать
nepster-web
@nepster-web Автор вопроса
CDbCommand не удалось исполнить SQL-запрос
Ответ написан
Комментировать
nepster-web
@nepster-web Автор вопроса
В таблице игр добавил еще 1 реляцию: waiting
public function relations()
    {
        return array(
            //'rule'    => array(self::HAS_MANY, 'GamesRuleModel',   '', 'on'=>'t.game_id=rule.game_id'),
            'proposal' => array(self::HAS_MANY, 'GameProposalModel', '', 'on'=>'t.game_id=proposal.game_id'),
            'waiting' => array(self::HAS_MANY, 'GameWaitingModel', '', 'on'=>'proposal.proposal_id=waiting.proposal_id'),
        );
    }


Такая вещь не работает:
$criteria->with = array(
             'proposal' => array('joinType'=>'LEFT OUTER JOIN'),
             'waiting.proposal',
        );


Теперь делаем запрос:
$game_id = 1;
          
        $criteria = new CDbCriteria;
        
        $criteria->select    = 't.game_id, t.game_name, t.alter_name';
        $criteria->condition = "t.game_id=:game_id AND proposal.status=-1";
        $criteria->params    = array(':game_id'=>$game_id);
        $criteria->together = true;
    
        $criteria->with = array(
             'proposal' => array('joinType'=>'LEFT OUTER JOIN'),
             'waiting',
        );
        
    
        $data = GamesModel::model()->find($criteria);
        

        echo '<pre>';
        print_r($data);
        echo '</pre>';


[b]Всплывает объект:[/b]

GamesModel Object
(
    [_new:CActiveRecord:private] => 
    [_attributes:CActiveRecord:private] => Array
        (
            [game_id] => 1
            [game_name] => Клабор (Деберц)
            [alter_name] => deberc
        )

    [_related:CActiveRecord:private] => Array
        (
            [proposal] => Array
                (
                    [0] => GameProposalModel Object
                        (
                            [user_rules] => 
                            [waiting_rules] => 
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [proposal_id] => 114
                                    [game_id] => 1
                                    [user_id] => 234
                                    [date] => 2014-01-13 17:10:28
                                    [status] => -1
                                    [rules] => [{"rule_id":"1","param":"30"},{"rule_id":"2","param":"0"},{"rule_id":"3","param":"4"},{"rule_id":"4","param":"301"},{"rule_id":"5","param":"0"}]
                                    [hash] => 61fe96c3d7291c7c04c6fcb71b8b49de
                                    [count_player] => 4
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 114
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                    [1] => GameProposalModel Object
                        (
                            [user_rules] => 
                            [waiting_rules] => 
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [proposal_id] => 113
                                    [game_id] => 1
                                    [user_id] => 500
                                    [date] => 2014-01-13 17:07:26
                                    [status] => -1
                                    [rules] => [{"rule_id":"1","param":"60"},{"rule_id":"2","param":"1"},{"rule_id":"3","param":"4"},{"rule_id":"4","param":"501"},{"rule_id":"5","param":"0"}]
                                    [hash] => 750da4a838006f676f0e0808ded1ac74
                                    [count_player] => 4
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 113
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                    [2] => GameProposalModel Object
                        (
                            [user_rules] => 
                            [waiting_rules] => 
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [proposal_id] => 112
                                    [game_id] => 1
                                    [user_id] => 234
                                    [date] => 2014-01-13 08:03:36
                                    [status] => -1
                                    [rules] => [{"rule_id":"1","param":"30"},{"rule_id":"2","param":"0"},{"rule_id":"3","param":"2"},{"rule_id":"4","param":"301"},{"rule_id":"5","param":"0"}]
                                    [hash] => b0105dc5a8908f82cb858987ea0cac50
                                    [count_player] => 2
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 112
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                )

            [waiting] => Array
                (
                    [0] => GameWaitingModel Object
                        (
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [waiting_id] => 182
                                    [proposal_id] => 114
                                    [user_id] => 234
                                    [sort] => 0
                                    [root] => 1
                                    [hash] => 61f7b277d2cb69b7af12bc0ab90dd814
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 182
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                    [1] => GameWaitingModel Object
                        (
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [waiting_id] => 183
                                    [proposal_id] => 113
                                    [user_id] => 231
                                    [sort] => 0
                                    [root] => 1
                                    [hash] => 61f7b277d2cb69b7af12bc0ab90dd814
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 183
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                    [2] => GameWaitingModel Object
                        (
                            [_new:CActiveRecord:private] => 
                            [_attributes:CActiveRecord:private] => Array
                                (
                                    [waiting_id] => 184
                                    [proposal_id] => 112
                                    [user_id] => 232
                                    [sort] => 0
                                    [root] => 1
                                    [hash] => 61f7b277d2cb69b7af12bc0ab90dd814
                                )

                            [_related:CActiveRecord:private] => Array
                                (
                                )

                            [_c:CActiveRecord:private] => 
                            [_pk:CActiveRecord:private] => 184
                            [_alias:CActiveRecord:private] => t
                            [_errors:CModel:private] => Array
                                (
                                )

                            [_validators:CModel:private] => 
                            [_scenario:CModel:private] => update
                            [_e:CComponent:private] => 
                            [_m:CComponent:private] => 
                        )

                )

        )

    [_c:CActiveRecord:private] => 
    [_pk:CActiveRecord:private] => 1
    [_alias:CActiveRecord:private] => t
    [_errors:CModel:private] => Array
        (
        )

    [_validators:CModel:private] => 
    [_scenario:CModel:private] => update
    [_e:CComponent:private] => 
    [_m:CComponent:private] => 
)


Теперь разбираемся, что тут у нас:

1) Данные об игре, в данном случае для теста я достал 3 параметра. ID и названия
2) Заявки на игру proposals
3) Пользователи которые ожидают игры waiting

Значит как это все дело выглядит на практике:
У нас есть сервер евент, который делает запрос на такой вот объект:
Получив объект яваскрипт рисует таблицу заявок по данным proposals и waiting
А так же по данным game обновляет статистику игру (к примеру сколько было сыграно игр за день, кол-во игроков онлайн и тп.)

Теперь моменты:
- если нет не одного ожидающего (нет записей waiting), все хорошо, объект приходит waiting пустой. Такого быть конечно не может, но на тесте проверяю.
- дальше, к примеру к этим трем заявкам присоединились еще игроки, заявки получили другой статус (-1 в ожидании, 1 идет игра, 0 игра закончена, -2 игра не состоялась) и как бы заявок нет.
делается запрос к серверу, и если заявок нет то возвращается пустота. В данном случае я яваскриптом отрисую таблицу, с надписью нет заявок. А вот как обновить статистические данные игры, если пришла пустота?

Тоесть задача сделать так, что если нет proposal, приходит просто объект game

По сути я это реализовывал по уровню школы:
// транзакция 

$data['game'] = .... findByPK($game_id);

if($data['game'])
{
        $data['proposal'] = ... findByAttibutes(array(...)) ;
        $data['waiting']  = ... findByAttibutes(array(...));
}

$transaction->commit();
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы