2012-08-15 11 views
5

Nie mogę znaleźć zbyt wiele dokumentacji na temat stosowania domyślnego zakresu do modelu w yii, zastanawiałem się, czy ktoś może wyjaśnić lub wskazać mi właściwy kierunek.zastosowanie domyślnego zakresu w odniesieniu do relacji w yii

Szybka wersja mojego pytania:

Czy jest możliwe aby dodać odniesieniu do domyślnego zakresu lub dodaj „z” Kryteria domyślnie do każdego wyszukiwania AR na modelu?

Długa wersja mojego pytania:

Krótkie podsumowanie mojej aplikacji:

mam dwa modele, provider i item. Które mają związek m: 1, w którym dostawca może mieć wiele przedmiotów, ale każda pozycja może mieć tylko jednego dostawcę.

tej pory mam te relacje:

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'), 
     ); 
    } 
    ... 
} 

w moim modelu pozycji już mam się defaultScope który odfiltrowuje wszystkie przedmioty w trybie offline (tzn wyświetla tylko elementy, które są ustawione na offline = false):

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

Co chcę teraz zrobić, to również odfiltrować elementy, w których ich dostawca jest ustawiony na tryb offline (tj. Pokazywać tylko elementy, gdzie provider.offline = false obok obecnego).

Próbowałem łączenia tabeli usługodawców w 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", 
    ); 
} 

Jednak DOŁĄCZ zastosowanie po oświadczeniu w sprawie, a causese błąd (CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'provider.offline' in 'on clause').

Próbowałem zostały również dodanie kryteriów do defaultScope:

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

ale pojawia się ten sam błąd: SQLSTATE [42S22]: Column not found: 1054 Unknown column 'provider.offline' w ' w sprawie klauzuli ").

Wszelkie sugestie?

Odpowiedz

6

Istnieje kilka rzeczy chciałbym spróbować:

pierwsze, zmienić swój stan zastosowanie do całej rzeczy (i nie zapomnij, że jeśli nie są przedmioty do dostawcy, nie powróci dostawcy)

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

drugie, spróbuj dodać zakresów do swoich modeli, a następnie odwołanie się do nich w zakresie domyślnym tak:

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

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

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

Oczywiście ! Umieszczałem warunek w głównym "warunku", a nie w "z". Twoja pierwsza sugestia działa doskonale, dzięki! – Stu

0

prostu miał podobny problem. Pierwsza sugestia Benjamina wskazała mi właściwy kierunek (bardzo doceniany!), Natknąłem się na nieoczekiwany problem, używając "warunku" i "z", o czym warto pamiętać.

Jeśli tabela, do której przyłączysz się ("dostawca" w przykładzie) ma swój własny defaultScope, wygląda na to, że zostanie zastosowana jako część klauzuli SQL ON, gdy użyjesz opcji "with", ograniczając liczbę zwracanych wierszy.

Ponieważ używane jest zewnętrzne sprzężenie, nadal otrzymujesz rekord z powrotem dla każdego wiersza w tabeli podstawowej ("element"), ale pola "dostawca" mogą być puste dla niektórych wierszy, jeśli domyślny profil dostawcy nie pozwala na zachowanie tych wierszy zwrócony.

Nie powoduje to problemu, dopóki nie spróbujesz zastosować warunku z jednym z tych pól dostawcy. Jest to wykonywane jako część klauzuli WHERE, która jest przetwarzana po połączeniu, ale ponieważ to pole jest puste, warunek się nie powiedzie, a rekord nie zostanie zwrócony.

W niektórych przypadkach może to być zachowanie chcesz, ale w innych przypadkach może chcesz przejść testy na polach „dostawca” do wewnątrz łączenia za pomocą opcji on:

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