применение области по умолчанию со ссылкой на отношение в yii



Я не могу найти слишком много документации по применению области по умолчанию к модели в yii, мне было интересно, может ли кто-то объяснить или указать мне правильное направление.



Краткий вариант моего вопроса:



Можно ли добавить отношение к области по умолчанию или добавить критерий " С " по умолчанию для каждого поиска AR в модели?



Длинная версия моего вопроса:



Краткое описание моего приложения:



У меня есть две модели, provider и item. Которые имеют отношение М: 1, где поставщик может иметь много элементов, но каждый элемент может иметь только одного поставщика.



Пока у меня есть такие отношения:



class Provider extends CActiveRecord
{
...
public function relations()
{
return array(
'items' => array(self::HAS_MANY, 'Item', 'id_provider', 'order'=>'rank DESC'),
);
}
...
}

class Item extends CActiveRecord
{
...
public function relations()
{
return array(
'provider' => array(self::BELONGS_TO, 'Provider', 'id_provider'),
);
}
...
}


В моей модели элементов у меня уже есть defaultScope, который отфильтровывает все автономные элементы (т. е. отображает только те элементы, которые настроены на offline = false):



public function defaultScope()
{
$alias = $this->getTableAlias(false,false);
return array(
'condition'=>"`$alias`.`offline` = false",
);
}


То, что я хочу сделать сейчас, - это также отфильтровать элементы, где их поставщик настроен на автономный режим (т. е. показывать только элементы, где provider.offline = false рядом с текущим item.offline = false).



Я попытался присоединиться к таблице providers в defaultScope:



public function defaultScope()
{
$alias = $this->getTableAlias(false,false);
return array(
'join'=>"JOIN `provider` AS `provider` ON `provider`.`id` = `$alias`.`id_provider`",
'condition'=>"`$alias`.`offline` = false AND `provider`.`offline` = false",
);
}


Однако соединение применяется после оператора ON, и вызывает ошибку (CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'provider.offline' in 'on clause').



Я также попытался добавить A с критериями в defaultScope:



public function defaultScope()
{
$alias = $this->getTableAlias(false,false);
return array(
'with'=>"provider",
'condition'=>"`$alias`.`offline` = false AND `provider`.`offline` = false",
);
}


Но я получаю ту же ошибку: SQLSTATE[42S22]: столбец не найден: 1054 неизвестный поставщик столбца.в автономном режиме " в "по пункту").



Есть предложения?

455   2  

2 ответов:

Есть пара вещей, которые я бы попробовал:

Во-первых, измените свое условие, чтобы применить его ко всему объекту (и не забывайте, что если нет элементов для поставщика, он не вернет поставщика)

public function defaultScope()
{
    return array(
        'with'=> array("provider" => array(
            'condition'=> "t.offline = false AND provider.offline = false",
        )
    );
}

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

public function defaultScope()
{
    return array(
        'scopes'=> array('default'),
    );
}

class Provider extends CActiveRecord
{
    ...
    public function scopes()
    {
        ...
    }
    ...
}

class Item extends CActiveRecord
{
    ...
    public function scopes()
    {
        ...
    }
    ...
}

Только что была аналогичная проблема. В то время как первое предложение Бенджамина указало мне правильное направление (очень ценю!), Я столкнулся с неожиданной проблемой, используя "условие" и "с", о которой было бы полезно знать.

Если таблица, к которой вы присоединяетесь ('provider' в примере), имеет свою собственную область defaultScope, то, по-видимому, она применяется как часть предложения SQL ON, когда вы используете 'with', ограничивая возвращаемые строки.

Поскольку используется внешнее соединение, вы все равно получаете запись назад для каждой строки в первичной таблице ("элемент"), но поля "поставщик" могут быть пустыми для некоторых строк, если defaultScope поставщика не позволяет возвращать эти строки.

Это не вызывает проблем, пока вы не попытаетесь применить "условие", включающее одно из этих полей поставщика. Это делается как часть предложения WHERE, которое обрабатывается после соединения, но поскольку это поле равно null, условие не будет выполнено, и запись не будет возвращена.

В некоторых случаях это может быть поведение, которое вы хотите, но в других случаях вы можете переместить тесты на полях 'provider' в пределах соединения с помощью на вариант:

public function defaultScope()
{
return array(
    'with'=> array("provider" => array(
        'condition'=> "t.offline = false",
        'on'=>"provider.offline = false",
    )
);
}

Comments

    Ничего не найдено.