使用 hasMany 关联 cakePHP 进行分页

发布于 2024-08-08 08:06:05 字数 1001 浏览 10 评论 0原文

我有两个表:

参赛者和投票 参赛者有很多投票

我尝试将(Vote.id)作为投票进行计数,以便我可以将其放在 记录集并对其进行分页,但我不知道将其放置在哪里。 我在 fields 数组上做到了这一点,但它给了我总票数 无论他们属于哪个参赛者。

选票在参赛者记录集中链接在一起,所以我 在我看来,我做了一个计数($contestant[Vote]),但这不可能 分页,我的客户希望能够对参赛者进行排序 投票。

在我看来,有没有办法做这样的事情?:

sort('Votes', 'count(Vote)'); ?>

或者我是否必须创建一个查询来计算所有投票 其中 Contestant.id = Votes.contestant_id ?

控制器参赛者:

function index() {
            $page = 'Contestants';
            $this->set('page', $page);
            $this->paginate =
            array(
                    'order' => 'id ASC',
                    'contain' => array(
                            'Vote' => array(
                                    'fields' => array("Vote.contestant_id",'Vote.id')
                            )
                    )
            $conditions ["Contestant.active"] = 1;
            $this->set('contestants', $this->paginate('Contestant',

$conditions)); }

I have two tables:

Contestant and Votes
Contestant hasMany Votes

I've tried doing a count(Vote.id) as Votes so I can place it on the
recordset and just paginate them but I have no idea where to place it.
I did it on the fields array but it gave me the total count of votes
regardless of the contestant they belong to.

The votes are linked together in the Contestant recordset so what I
did was on my view I did a count($contestant[Vote]) but this can't be
paginated and my client wants to be able to sort the contestants by
votes.

Is there a way I can do something like this on my view?:

sort('Votes', 'count(Vote)'); ?>

Or do I have to create a query which does a count for all the votes
where Contestant.id = Votes.contestant_id ?

Controller Contestant:

function index() {
            $page = 'Contestants';
            $this->set('page', $page);
            $this->paginate =
            array(
                    'order' => 'id ASC',
                    'contain' => array(
                            'Vote' => array(
                                    'fields' => array("Vote.contestant_id",'Vote.id')
                            )
                    )
            $conditions ["Contestant.active"] = 1;
            $this->set('contestants', $this->paginate('Contestant',

$conditions));
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

司马昭之心 2024-08-15 08:06:05

查看 deceze 在这个问题中的回复: CakePHP mathematic-calculation field?

本质上是你我猜想做这样的事情:

'contain' => array(
    'Vote' => array(
        'fields' => array('SUM(Vote.id) AS Contestant__votes'),
        'group'  => array('Vote.contestant_id'),
    )
)

Check out deceze's response in this question: CakePHP mathematic-calculation field?

Essentially you want to do something like this I'm guessing:

'contain' => array(
    'Vote' => array(
        'fields' => array('SUM(Vote.id) AS Contestant__votes'),
        'group'  => array('Vote.contestant_id'),
    )
)
錯遇了你 2024-08-15 08:06:05

由于 cakephp 不支持可包含行为中的分组,我尝试了一种不同的方法。为投票模型创建分页变量(所有这些都是在参赛者控制器中完成的):

var $paginate = array(
    'Vote'=>array(
        'limit'=>5,
        'fields' => array(
        'Contestant.*, count(Vote.contestant_id) as Contestant_votes, Vote.id'
        ),
        'group' => array(
        'Vote.contestant_id'
        ),
        'order' => array(
        'Contestant_votes Desc'
        )
    ),
    'Contestant'=>array(
        'limit'=>5,
        'order' => array(
        'Contestant.id Desc'
        )
    )
);

现在在我的控制器中我执行以下操作:

function index() {
    $page = 'Contestants';
    $this->set('page', $page);  
    $conditions ["Contestant.active"] = 1;
    $this->set('contestants', $this->paginate($this->Contestant->Vote,$conditions));
}

现在参赛者按总投票数排序,尽管我仍然不知道如何进行排序将 Contestant_votes 放置为分页器变量,因为在记录集中,它位于它自己的数组中,而不是用于分页的任何模型数组中。

谢谢马特·哈金斯,你的方法引导我找到了这个解决方案。

Since cakephp doesn't support group by in containable behavior I tried a different approach. Create the paginate var for the vote model instead (All of this is done in the Contestants Controller):

var $paginate = array(
    'Vote'=>array(
        'limit'=>5,
        'fields' => array(
        'Contestant.*, count(Vote.contestant_id) as Contestant_votes, Vote.id'
        ),
        'group' => array(
        'Vote.contestant_id'
        ),
        'order' => array(
        'Contestant_votes Desc'
        )
    ),
    'Contestant'=>array(
        'limit'=>5,
        'order' => array(
        'Contestant.id Desc'
        )
    )
);

And now in my controller I do the following:

function index() {
    $page = 'Contestants';
    $this->set('page', $page);  
    $conditions ["Contestant.active"] = 1;
    $this->set('contestants', $this->paginate($this->Contestant->Vote,$conditions));
}

Now the contestants are ordered by their total vote tally, although I still can't figure how to place the Contestant_votes as a paginator variable since in the record set it's in a array of it's own and not in any of the model arrays used to paginate.

Thanks Matt Huggins your approach was the one that led me to this solution.

§普罗旺斯的薰衣草 2024-08-15 08:06:05

添加:您还想按投票数(总票数)升序还是降序排序?如果是的话,用cakephp默认的分页方式是不太容易做到的。

为此,您需要进行一些调整。以下是有关此技巧的详细信息: CakePHP 高级分页– 按派生字段排序

希望您会发现它有帮助。

谢谢
阿德南

Addition: Do you also want to sort by Votes (total votes) ascending or descending? If yes, you can not do it easily by the default pagination method of cakephp.

For that you need a little tweak. Here is the details about this trick: CakePHP Advanced Pagination – sort by derived field

Hope you'd find it helpful.

Thanks
Adnan

太傻旳人生 2024-08-15 08:06:05

对于您定义的特定关系,counter- 可以很好地满足您的需求 -缓存

您需要在 contestants 表中定义一个新字段:vote_count。然后,在您的投票模型中,您需要稍微更新 $belongsTo 定义:

class Votes extends AppModel
{
    var $belongsTo = array(
        'Contestant' => array( 'counterCache' => true )
    );
}

现在,只要保存投票记录,父参赛者的 vote_count 字段就会更新被更新。现在,您可以像对任何其他“参赛者”字段一样按 Contestant.vote_count 进行排序:

class ContestantsController extends AppController
{
    // Controller stuff that comes before...

    function index()
    {
        $this->paginate = array( 'Contestant' => array(
            'conditions' => array( 'Contestant.active' => 1 ),
            'order' => array( 'Contestant.vote_count' => 'DESC' ),
        ));

        $contestants = $this->paginate('Contestants');

        $this->set( compact('contestants'));
    }

    // Controller stuff that comes after...
}

For the specific relationship you define, your needs are well-served by counter-caching.

You will need to define a new field in your contestants table: vote_count. Then, in your Votes model, you'll need to update the $belongsTo definition slightly:

class Votes extends AppModel
{
    var $belongsTo = array(
        'Contestant' => array( 'counterCache' => true )
    );
}

Now, anytime a Vote record is saved, the vote_count field of the parent Contestant will be updated. Now you can simply sort by Contestant.vote_count as you would any other Contestant field:

class ContestantsController extends AppController
{
    // Controller stuff that comes before...

    function index()
    {
        $this->paginate = array( 'Contestant' => array(
            'conditions' => array( 'Contestant.active' => 1 ),
            'order' => array( 'Contestant.vote_count' => 'DESC' ),
        ));

        $contestants = $this->paginate('Contestants');

        $this->set( compact('contestants'));
    }

    // Controller stuff that comes after...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文