1

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 个动作来获得它们)

4

2 回答 2

0

正如您在底部布局中的 sql_dump 中看到的那样,Cakephp automagic 实际上并没有加入表。

您将看到以下查询。

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) 

很清楚,它实际上并不是连接表,因此您需要按照以下方式进行操作。

以下将对您有所帮助,因为我已经对其进行了测试。

在 Player Controller 中,您需要先取消绑定得分模型,然后使用自定义代码加入得分表,如下所示。

在播放器模型中创建一个虚拟字段,如下所示。

<?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));?>
于 2013-01-24T04:42:11.347 回答
0

所以,Player有很多Scores...

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

...这意味着您的find()inPlayersController可以是...

$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',
        ),
    )
);

希望你明白这一点。

于 2013-01-23T19:08:09.093 回答