2010-01-18 28 views
2

我使用Containable行爲來獲取評論列表(belongsTo Post,屬於問題;問題hasMany Post和Post hasMany Comments;所有這些屬於用戶) 。CakePHP在1個級別以上查詢結果

$data = $this->Question->find ('first', 
    array ('contain' => 
     array ('User', 
       'Post' => array ('User', /* 'order' => 'User.created DESC'*/) 
     ) 
    ) 
); 

它有效,當我註釋掉上面評論中的部分。我想這是可以預料的,但我想要的是找到的所有帖子,應按照他們所屬的「用戶」的「創建」字段的順序進行排序。我如何在CakePHP中完成更深層次的排序?我總是得到,「警告(512):SQL錯誤:1054:'訂單子句'中的未知列'User.created'」

感謝您的幫助!

回答

3

此外,您可能會嘗試組:

+0

我看着調試輸出,你是對的,它不執行'JOIN'。這是不幸的,是否真的沒有其他方法讓CakePHP來做到這一點? – ash 2010-01-19 06:25:56

+0

http://teknoid.wordpress.com/2008/07/17/forcing-an-sql-join-in-cakephp/ 從teknoid解決如何強制左連接解除hasMany並替換與臨時hasOne確實使用連接。閱讀它並讓我知道這是否適用於您,否則我可以發佈專門的連接代碼供您查看。 – 2010-01-19 15:32:16

+0

確實,它確實有效。謝謝您的幫助! – ash 2010-01-20 00:06:16

0

檢查您的遞歸值。如果它太有限制,它將忽略可控鏈接,IIRC。我記得幾次碰到這個。我會嘗試包含多個模型,但我的recursive選項設置爲0並且沒有任何內容會被拉下。舉例來說,我認爲1(默認值)就足夠了,但也許你已經明確地將它設置爲0的某處?在相關的表從一個不使用加入了查找調用

$this->Question->order = 'Question.created DESC'; 
+0

我實際上放棄了遞歸選項,因爲我相信Containable會爲您選擇最合適的選項(如果指定它,事情只會變得更糟)。 – ash 2010-01-19 05:55:31

+0

這不是我的經驗。這已經有一段時間了,但我依稀記得在一點上失去了幾小時,因爲我假設了同樣的事情。這可能是因爲我的記憶在這一點上是不準確的。 – 2010-01-19 12:35:24

0

您可以將呼叫前加入尋找()以下。

將您的調試級別設置爲大於1的值,以便您可以看到查詢日誌並確保Cake沒有執行兩個查詢來獲取您的數據。如果是這種情況,那麼第一個查詢實際上並沒有引用第二個表。

如果您想在這些情況下手動強制連接,可以使用Nate在以下鏈接中概述的Ad-Hoc連接方法。

http://bakery.cakephp.org/articles/view/quick-tip-doing-ad-hoc-joins-in-model-find

+1

這將按照「created」字段對問題進行排序,這不是我想要的。也許你的意思是'$ this-> Question-> Post-> order ='User.created DESC';'? – ash 2010-01-19 06:24:27

+0

無論如何,我試過purohit的例子,但它似乎並沒有工作。也許它是在模型的不同實例上設置排序順序,而不是Question模型實際使用的排序順序......? – 2012-01-18 01:24:34

1

我發現兩種方法來解決這個問題。 第一個是直接在模型中定義第二級關聯。 現在您將可以隨時訪問這些數據。 它應該是這個樣子.....

var $belongsTo = array(
'Foo' => array(
    'className' => 'Foo', //unique name of 1st level join (Model Name) 
    'foreignKey' => 'foo_id', //key to use for join 
    'conditions' => '', 
    'fields' => '', 
    'order' => '' 
), 
'Bar' => array(
    'className' => 'Bar', //name of 2nd level join (Model Name) 
    'foreignKey' => false, 
    'conditions' => array(
    'Bar.id = Foo.bar_id' //id of 2nd lvl table = associated column in 1st level join 
), 
    'fields' => '', 
    'order' => '' 
) 
); 

這種方法的問題在於,它可以使普通的查詢要複雜得多,他們需要的話。 因此,您也可以將第二級查詢直接添加到te find或paginate語句中,如下所示:(注意:我發現由於某些原因,您不能在第二級聯接中使用$ belongsTo關聯,並且需要重新定義它們,如果他們已經被定義。例如,如果「富」在$屬於關聯已經定義,你需要創建一個副本「Foo1」,使協會工作,如下面的例子。)

$options['joins'] = array(

array('table' => 'foos', 
    'alias' => 'Foo1', 
    'type' => 'inner', 
    'conditions' => array(
    'CurrentModel.foo_id = Foo1.id' 
) 
), 
array('table' => 'bars', 
    'alias' => 'Bar', 
    'type' => 'inner', 
    'foreignKey' => false, 
    'conditions' => array(
    'Bar.id = Foo1.bar_id' 
) 
) 
); 

$options['conditions'] = array('Bar.column' => "value"); 
$this->paginate = $options; 
$[modelname] = $this->paginate(); 
$this->set(compact('[modelname]')); 

我希望這是明確的足以理解並幫助某人。

0

是的,我不知道如何基於相關/相關模型進行排序,所以最終使用Set::sort()方法。結帳this article爲一個很好的解釋。

// This finds all FAQ articles sorted by: 
// Category.sortorder, then Category.id, then Faq.displaying_order 
$faqs = $this->Faq->find('all', array('order' => 'displaying_order')); 
$faqs = Set::sort($faqs, '{n}.Category.id', 'ASC'); 
$faqs = Set::sort($faqs, '{n}.Category.sortorder', 'ASC'); 

...是的,它應該可能是Category->find(),但不幸的是原始開發人員沒有這樣編寫代碼,我不想重寫視圖。