在find方法中加入belongsTo

时间:2013-01-23 16:54:49

标签: cakephp join model model-associations

Score属于Player

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

PlayersController中,我希望获得球员得分及其详细信息。

问题#1 :如何在belongsTo方法结果中包含find模型? (加入)

问题#2 :如何获得属于该玩家的所有得分距离(Score.distance)的总和? (我的意思是SUM(Score.distance),按Score.player_id分组)

关于Q1的注意事项:因为每个玩家都有很多分数,所以我不喜欢在我在该控制器中使用的每个find方法中加入分数。我想让他们只进行一次行动)

1 个答案:

答案 0 :(得分:0)

Cakephp自动实际上并没有像你在底部布局中的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));?>