2011-11-27 47 views
1

我有一個帶有3個$ belongsTo引用密鑰的活動表。我需要來自這些ID的連接信息,即顯示commenttext - 我不想將文本存儲兩次...(對帖子和主題也一樣)。Cakephp - 僅在ID不爲空時加入

活動表:id | post_id | comment_id | topic_id
在每一行中,只設置post_id或comment_id或topic_id,其他兩個id字段爲NULL。

那麼也就是說,如果POST_ID = 55,COMMENT_ID = NULL,topic_id = NULL我得到這個:

Array 
(
[0] => Array 
    (
     [Activity] => Array 
      (
       [id] => 1 
       [post_id] => 55 
       [comment_id] => 
       [topic_id] => 
      ) 

     [Post] => Array 
      (
       [id] => 55 
       [name] => Post #1 
       [description] => This is Post #1. 
       ... 
      ) 

     [Comment] => Array 
      (
       [id] => 
       [post_id] => 
       [titel] => 
       [description] => 
       ... 
       [created] => 
       [modified] => 
      ) 

     [Topic] => Array 
      (
       [id] => 
       ... 
       [created] => 
       [modified] => 
      ) 
    ) 

[1] => Array 
    (
     ... 

有沒有辦法只有在參考id爲NOT NULL加入?我不想在用php for-each循環查找後殺死空數組。

另一個想法是這個數據庫表:id | activitytype_id |根據activitytype_id refid加入動態綁定必要的表。 - 那也不行......

這就是我想要的 - 這可能嗎?

Array 
(
[0] => Array 
    (
     [Activity] => Array 
      (
       [id] => 1 
       [post_id] => 55 
       [comment_id] => 
       [topic_id] => 
      ) 

     [Post] => Array 
      (
       [id] => 55 
       [name] => Post #1 
       [description] => This is Post #1. 
       ... 
      ) 
    ) 

[1] => Array 
    (
     [Activity] => Array 
      (
       [id] => 2 
       [post_id] => 
       [comment_id] => 2 
       [topic_id] => 
      ) 

     [Comment] => Array 
      (
       [id] => 2 
       [post_id] => 4 
       [titel] => Blabla 
       [description] => This is the comment description 
       ... 
       [created] => 2011-01-01 01:30:00 
       [modified] => 2011-01-01 01:30:00 
      ) 
    ) 

[2] => Array 
    (
     ... 

在此先感謝! :-)

回答

2

您需要查詢數據庫以找出哪些ID爲null,然後再次查詢數據庫以獲取相關數據。

$activity = $this->Activity->read(null, 1); 
// some logic to find foreign key with non-null value 
$activity[$model] = $this->{$model}->read(null, $id); 

我不會浪費你的時間寫兩個查詢;讓CakePHP在單個查詢中獲取所有結果。 :)

$activity = $this->Activity->findById(1); 

只需添加到您的模型,從結果中過濾出空值:

public function afterFind($results, $primary = false) { 
    return Hash::filter($results); 
} 
+0

謝謝!其實我想避免Set :: filter,因爲它也使用了array_filter的foreach循環,但性能看起來不錯。 :-) – shoemakerlevy9

+0

沒問題。框架顯然會增加開銷,因此您可以通過忽略空值並且不過濾掉它們或者添加一些緩存(如果可能的話使用該特定結果集)來節省一些CPU週期。儘量避免過早優化,首先找到真正的瓶頸。 ;) – deizel

0

您可以隨時手動進行連接。你想要的是做INNER JOIN而不是蛋糕做的LEFT JOIN。你也可以做一個afterFind()來刪除這個東西。

在模型中

你在哪裏使用find方法

function afterFind($results){ 
    foreach($results as $k => $result){ 
     if (empty($result['Post']['id'])){ 
      unset($results[$k]['Post']); 
     } 
     if (empty($result['Comment']['id'])){ 
      unset($results[$k]['Comment']); 
     } 
     if (empty($result['Topic']['id'])){ 
      unset($results[$k]['Topic']); 
     } 
    } 
} 

聯接是一種更直接的解決方案雖然。

+0

謝謝!我嘗試了INNER JOIN,但這是一個棘手的問題(在第二次連接後得到一個空的結果數組),所以我決定使用Set :: filter($ results,true);在afterFind中。但是你的解決方案也是可能的。 :-) – shoemakerlevy9