2013-01-23 67 views
1

Score屬於Player加入屬於關聯:在find方法

class Score extends AppModel { 
    public $name = 'Answer'; 
    public $belongsTo = array('Player'); 
} 

PlayersController,我想球員的得分,他的細節。

問題1:如何在find方法結果中包含belongsTo模型? (加入)

問題#2:如何獲得屬於該玩家的所有得分距離的總和(Score.distance)? (我的意思是SUM(Score.distance),按Score.player_id

注意事項Q1:因爲每個球員都有很多的分數,我不喜歡參加的分數在每個find方法我在控制器使用。我想,讓他們在短短1個行動)

回答

0

Cakephp automagic並不實際連接表,正如你可以在底部的佈局中的sql_dump中看到的那樣。

你會看到下面的查詢。

SELECT `Player`.`id`, `Player`.`name`, `Player`.`created` FROM `players` AS `Player` WHERE `Player`.`id` = 10 GROUP BY `Player`.`id` 

SELECT `Score`.`id`, `Score`.`player_id`, `Score`.`scores` FROM `scores` AS `Score` WHERE `Score`.`player_id` = (10)

很明顯,它不是真正的連接表,所以你需要按照以下方式做。

以下將幫助你,因爲我已經測試過它。

在播放器控制器中,您需要首先解除分數模型,然後自定義代碼以加入分數表,如下所示。

在玩家模型中創建一個虛擬字段,如下所示。

<?php 
class Player extends AppModel 
{ 
    var $name = 'Player'; 
    var $displayField = 'name'; 

    var $virtualFields = array 
    (
     'Distance' => 'SUM(Score.scores)' 
    ); 

    var $hasMany = array 
    (
     'Score' => array 
     (
      'className' => 'Score', 
      'foreignKey' => 'player_id', 
      'dependent' => false, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'exclusive' => '', 
      'finderQuery' => '', 
      'counterQuery' => '' 
     ) 
    ); 
} 
?>

爲了測試我手動添加conditions找到玩家人數10 scores

<?php 
class PlayersController extends AppController { 

    var $name = 'Players'; 

    function index() 
    { 

     $this->Player->unbindModel(array 
     (
      'hasMany' => array 
      (
       'Score' 
      ) 
     )); 

     $this->Player->bindModel(array 
     (
      'belongsTo' => array 
      (
       'Score' => array 
       (
        'foreignKey' => false, 
        'conditions' => array 
        (
         'Player.id = Score.player_id' 
        ) 
       ) 
      ) 
     )); 

     $order = "Player.id"; 
       $direction = "asc"; 
       if(isset($this->passedArgs['sort']) && $this->passedArgs['sort']=="Distance") 
       { 
         $order = $this->passedArgs['sort']; 
        $direction = $this->passedArgs['direction']; 
        unset($this->passedArgs['sort']); 
        unset($this->passedArgs['direction']); 
       } 

       $this->pagination = array(); 

       $this->pagination = array 
       (
        'conditions' => array 
        (
        'Score.player_id' => 10 
        ), 
        'fields' => array 
        (
         'Player.*', 
         'SUM(Score.scores) AS Distance' 
        ), 
        'group' => array 
        (
         'Score.player_id' 
        ), 
        'limit' => 15, 
         'order'=>$order." ".$direction 
       ); 

       $playersScore = $this->paginate('Player'); 
    } 
} 
?>

,所得陣列將類似於下。

Array 
(
    [0] => Array 
    (
     [Player] => Array 
     (
      [id] => 10 
      [name] => Dexter Velasquez 
      [created] => 2012-08-02 12:03:07 
      [Distance] => 18 
     ) 
    ) 
)

對於測試我已使用Generate Mysql Data

爲如下排序上面的鏈接鏈接

<?php $direction = (isset($this->passedArgs['direction']) && isset($this->passedArgs['sort']) && $this->passedArgs['sort'] == "Distance" && $this->passedArgs['direction'] == "desc")?"asc":"desc";?>

和顯示。

<?php echo $this->Paginator->sort('Distance','Distance',array('direction'=>$direction));?>
+0

cakephp實際上查找相關表並將數據追加到數組。所以你需要手動強制cakephp解除綁定舊的關係和bindModel連接...因爲只要沒有加入表,你不能在查詢中使用其他表字段....希望你明白我的意思。 –

+0

謝謝。它工作正常。但我怎樣才能用分頁組件做到這一點?並按距離排序。 (或其他列) – mrdaliri

+0

您不必擔心分頁問題,​​因爲每個分頁頁面都會執行此代碼,因此您的數據足夠精確 –

0

所以,Player有許多Scores ...

class Player extends AppModel { 
    public $name = 'Player'; 
    public $hasMany = array('Score'); 
} 

...這意味着你find()PlayersController可以是這樣的......

$players = $this->Player->find(
    'all', 
    array(
     'contain' => array('Score'), // <-- If you're not using Containable Behavior, remove. 
     'conditions' => array('Player.id' => $id), // <-- Change or remove as necessary. 
     'fields' => array(
      'Player.id', 
      'Player.name', 
      'Sum(Score.distance) as sum_dist', 
     ), 
     'group' => array(
      'Player.id', 
      'Player.name', 
     ), 
     'order' => array(
      'Player.name', 
     ), 
    ) 
); 

希望你明白了。

+0

謝謝,但它不工作:SQLSTATE [42S22]:列未找到:在「字段列表」 – mrdaliri

+0

1054未知列「Score.distance」 @kikio您正在使用中可容納的行爲嗎?或者您是否刪除了「包含」參數並正確設置了「遞歸」? – ianmjones