<rmcreative>

RSS

Yii: параметры именованных групп условий в отношениях

20 февраля 2011

До готовящегося релиза 1.1.7 можно было применить именованные группы условий, они же named scopes, к отношениям:

$posts=Post::model()->with('comments:recently:approved')->findAll();

Но нельзя было указать для них параметры. Решил эту проблему creocoder. Теперь, слив свежий код из SVN, можно делать так:

$users=User::model()->findAll(
    'with'=>array(
        'posts'=>array(
            'scopes'=>array(
                'rated'=>5,
            ),
        ),
    ),
);

Комментарии RSS

  1. №3937
    Ekstazi
    Ekstazi 20.02.2011, 11:59:22

    А с моим патчем пока никак ? P.S.: может есть смысл сменить формат вызова на User::model()->with('posts:related=5')->findAll() ?

    Но остается проблема с придумыванием синтаксиса для with для случаев когда у именованой группы параметров больше чем один

  2. №3940
    Sam
    Sam 20.02.2011, 13:38:51

    Ekstazi, патч пока изучается. Смена формата меня пока не очень привлекает: легко будет ошибиться, да и разбор строк — штука не совсем быстрая. К тому же, в текущей реализации нет проблем с несколькими параметрами.

  3. №3941
    porcelanosa
    porcelanosa 20.02.2011, 15:04:52

    А где можно на русском почитать про именованные группы условий? Или хотя бы на английском...

  4. №3942
    Ekstazi
    Ekstazi 20.02.2011, 15:53:49
  5. №3946
    Creocoder
    Creocoder 20.02.2011, 19:36:17

    Ekstazi Никакой проблемы с синтаксисом в случае, если у именованной группы больше одного параметра нет. Например:

    $users=User::model()->findAll(
        'with'=>array(
            'posts'=>array(
                'scopes'=>array(
                    'rated'=>array(5,6),
                ),
            ),
        ),
    );
  6. №4151
    vamp
    vamp 23.03.2011, 10:14:20

    Sam, спешу поправить тебя...

    1.

    ->with(array(
        'scopes'=>array(
            'scopeName'=>array('paramValue'),   
        ),
    ))

    не работает (если scopeName не является методом, а определен в scopes())

    1. то, что с помощью этого:
    public function scopes(){
            return array(
                'bySubagency'=>array(
                    'condition'=>'subagencyId=?',
                )
            );
        }

    нельзя сделать:

    $model->bySubagency(6)->findAll()

    тоже не есть гуд, так что есть еще куда развивать тему (пока что лучше, чем ничего, но хуже, чем что-то).

  7. №4152
    vamp
    vamp 23.03.2011, 10:28:42

    Предположу даже, что вторая проблема решается проще некуда:

    Index: /framework/db/ar/CActiveRecord.php
    ===================================================================
    --- /framework/db/ar/CActiveRecord.php  (revision 3104)
    +++ /framework/db/ar/CActiveRecord.php  (working copy)
    @@ -206,7 +206,10 @@
            $scopes=$this->scopes();
            if(isset($scopes[$name]))
            {
    -           $this->getDbCriteria()->mergeWith($scopes[$name]);
    +           $scope=$scopes[$name];
    +           if(!empty($parameters))
    +               $scope['params']=(!empty($scope['params']))?CMap::mergeArray((array)$scope['params'], $parameters):$parameters;
    +           $this->getDbCriteria()->mergeWith($scope);
                return $this;
            }

    Сорри, за небольшой флуд, просто немного надоело, что в issues такие вещи могут оежать месяцами

  8. №4199
    Sam
    Sam 24.03.2011, 22:26:34

    vamp, гайд как-бы намекает:

    Примечание: Именованные группы параметров, применяемые к реляционным моделям, должны описываться в методе CActiveRecord::scopes, поэтому они не могут быть параметризованы.

    scopes и именованные методы с параметрами — штуки совершенно разные.

    Кстати, спасибо за напоминание проверить документацию, это замечание я случайно из SVN выпилил.

  1. Почта опубликована не будет.

  2. Можно использовать синтаксис Markdown или HTML.

  3. Введите ответ в поле. Щёлкните, чтобы получить другую задачу.