2012-08-15 62 views
5

我找不到太多關於在yii中將默認範圍應用於模型的文檔,我想知道是否有人能夠向正確的方向解釋或指出我。應用默認範圍引用yii中的關係

快速版本我的問題:

是否有可能的關係添加到默認範圍,或在默認情況下在模型中的每個AR搜索添加「與」標準是什麼?

加長版我的問題:

我的應用程序的快速摘要:

我有兩個型號,provideritem。哪個供應商可以擁有多個項目,但每個項目只能擁有一個供應商。

到目前爲止,我有以下關係:

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並排的項目)。

我試過在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", 
    ); 
} 

然而JOIN的ON語句後適用,以及一個根源探析誤差(CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'provider.offline' in 'on clause')。

我也試圖與標準的defaultScope添加:

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

,但我得到了同樣的錯誤:SQLSTATE [42S22]:列未發現:在1054未知列「provider.offline」'在條款')。

有什麼建議嗎?

回答

6

有一對夫婦的事情,我會嘗試:

首先,改變你的條件適用於整個事情(不要忘記,如果沒有物品的提供者,它不會返回供應商)

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() 
    { 
     ... 
    } 
    ... 
} 
+0

當然!我把條件放在主要的「條件」聲明中,而不是在「與」之中。你的第一個建議很完美,謝謝! – Stu 2012-08-16 08:07:53

0

只是有類似的問題。雖然本傑明的第一個建議指出了我朝着正確的方向(非常感謝!),但我發現了一個意外的問題,使用「條件」和「與」,這可能有助於瞭解。

如果您加入的表(示例中的'provider')有其自己的defaultScope,則當您使用'with'時限制返回的行時,它會顯示爲SQL ON子句的一部分。

由於使用了外部聯接,所以仍然會爲主表('item')中的每一行獲取一條記錄,但如果提供者的defaultScope阻止了這些行,那麼某些行的'provider'字段可能爲null回。

這不會導致問題,直到您嘗試應用涉及其中一個提供程序字段的「條件」。這是作爲在連接之後處理的WHERE子句的一部分完成的,但是由於該字段爲空,條件將失敗,並且該記錄不會被返回。

在某些情況下,這可能是你想要的行爲,但在其他情況下,您可能希望通過使用on選項上的「供應商」字段移動的測試中加入:

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