2015-11-06 67 views
4

我有兩個模型通過一個聯結表相關。Yii2如何檢查兩個模型是否已經鏈接

$model->link()是用來建立兩個模型之間關係的方法。它基本上用兩個型號的相應鍵填充聯結表。

如果兩個模型已鏈接,並且我嘗試再次鏈接它們,則會出現錯誤,因爲密鑰對已存在於聯結表中。然後我需要在嘗試鏈接模型之前檢查這個關係是否存在。

我想我可以爲聯結表創建一個模型並查詢正確的記錄。該查詢的結果會告訴我是否需要執行鏈接。

的問題是:

是否有執行該檢查短暫而簡單的方法,使用一些警予內置的方法?

回答

3

ActiveQueryexists()方法,可以做你需要的。假設您有一個Book類,它鏈接到Author類。所以BookgetAuthor()方法。這裏是你如何找出是否相關記錄存在:

$book->getAuthor()->exists(); 

注意$book->author(如果它是一個hasMany關係或數組)返回的Author一個實例,而getAuthor()返回ActiveQuery實例。

執行exists()仍會運行一個SQL查詢,就像$book->author一樣,但該查詢比實際獲取數據和創建相應模型更有效。另一方面,在許多情況下,性能改進可以忽略不計,因此您只需運行isset($book->author)並完成它。

+0

這將適用於我所需要的。我會用'where()''ActiveQuery'方法過濾結果以檢查特定記錄。非常感謝。 – Arge

+0

通常,最好有方法返回「ActiveQuery」或其後代,而不是返回模型數組,因爲在前一種情況下,可以向原始查詢添加更多條件。如果查詢有其他條件,你可能想用'andWhere()'來完成。 – Beowulfenator

+0

它如何與hasMany協同工作? – Herokiller

2

我認爲最簡單的方法就是調用關係方法。 使用模型Foo和模型Bar的關係方法getBar()(使用via結點表定義)(new Foo) - > bar如果沒有鏈接,則爲null。當然這在一對一關係的情況下是有效的。對於一對多你必須檢查結果數組。

+0

你是對的,假設你需要的到底是什麼在關係中指定。如果需要進一步操作查詢,獲取查詢本身是一個更好的主意。 – Beowulfenator

+0

對於多數人來說如何? – user3574492

1

我已經添加了這個方法需要被鏈接 模型(對我來說這是許多到許多關係):

/** 
* @inheritdoc 
*/ 
public function link($name, $model, $extraColumns = []) 
{ 
    $exists = $this->getJunctionModel() 
     ->where(['other_model_id' => $model->primaryKey]) 
     ->exists(); 

    if (!$exists) { 
     parent::link($name, $model, $extraColumns); 
    } 
} 
相關問題