【问题标题】:Complicated Query in CakePHPCakePHP 中的复杂查询
【发布时间】:2011-07-12 12:48:31
【问题描述】:

我想知道你们是否可以帮助解决一个复杂的问题。
我有三张表。

用户、职位和评论。

职位分配给用户,但任何用户都可以对职位发表评论。
目前,通过传统方式烘焙后,View Job 视图在底部显示相关 cmets。但是,评论表显示一个数字user_id,而我希望它显示与所述user_id 匹配的“用户名”。

View Job 视图中,我有这个数组,以及它们各自的键:

$job;
$job['Users'];
$job['Comments'];
$job['Job'];

这是我对 $job 数组的调试输出。

Array
(
    [Job] => Array
        (
            [id] => 1
            [user_id] => 1
            [title] => New Job
            [body] => adsljbfalwsjbflkjb
            [deadline] => 2011-07-15
            [completed] => 0
        )

    [User] => Array
        (
            [id] => 1
            [username] => dan
            [password] => 2fd27a6319ef3faf9ed55b59830d786b5ed890be
        )

    [Comment] => Array
        (
            [0] => Array
                (
                    [id] => 3
                    [job_id] => 1
                    [user_id] => 2
                    [hours] => 6
                    [body] => Comment from Phil
                    [date] => 2011-07-12
                )

            [1] => Array
                (
                    [id] => 2
                    [job_id] => 1
                    [user_id] => 1
                    [hours] => 2
                    [body] => This is a Comment from the 9th
                    [date] => 2011-07-09
                )

        )

)

我能不能用这些来显示用户名而不是 user_id?我要修改模型吗?控制器?
我对 CakePHP 比较陌生,虽然我已经掌握了基础知识,但我在处理像这样的更复杂的查询时遇到了困难。

这是我要更改的视图文件:

<div class="related">
    <h3><?php __('Comments'); ?></h3>
    <?php if (!empty($job['Comment'])): ?>
        <table cellpadding = "0" cellspacing = "0">
            <tr>
                <th><?php __('User'); ?></th>
                <th><?php __('Date'); ?></th>
                <th><?php __('Hours'); ?></th>
                <th><?php __('Body'); ?></th>
                <th class="actions"><?php __('Actions'); ?></th>
            </tr>
            <?php
            $i = 0;
            foreach ($job['Comment'] as $comment):
                $class = null;
                if ($i++ % 2 == 0) {
                    $class = ' class="altrow"';
                }
                ?>
                <tr<?php echo $class; ?>>
                    <td><?php echo $comment['user_id']; ?></td> // NEEDS TO BE USERNAME NOT USER ID
                    <td><?php echo $comment['date']; ?></td>
                    <td><?php echo $comment['hours']; ?></td>
                    <td><?php echo $comment['body']; ?></td>                   
                    <td class="actions">
                        <?php echo $this->Html->link(__('View', true), array('controller' => 'comments', 'action' => 'view', $comment['id'])); ?>
                        <?php echo $this->Html->link(__('Edit', true), array('controller' => 'comments', 'action' => 'edit', $comment['id'])); ?>
                        <?php echo $this->Html->link(__('Delete', true), array('controller' => 'comments', 'action' => 'delete', $comment['id']), null, sprintf(__('Are you sure you want to delete # %s?', true), $comment['id'])); ?>
                    </td>
                </tr>
            <?php endforeach; ?>+
        </table>
    <?php endif; ?>

</div>

感谢您的帮助!

【问题讨论】:

  • 在您看来,debug($job) 并发布您所拥有的。我敢打赌它已经在里面了。
  • @Jason McCreary 我已经用输出更新了问题。
  • 需要查看一些控制器/模型代码,但是这是可能的。你在修改$this-&gt;Model-&gt;recursive吗?这可以影响关联的深度,而无需任何额外的工作。
  • 您必须在模型上设置 $displayField。请参阅下面的答案...
  • $this-&gt;Model-&gt;recursive 不适合您,因为您正在寻找模特孩子的另一个父母。

标签: php cakephp


【解决方案1】:

我通过在您要从中检索名称的模型上运行 find('list') 解决了同样的问题。

在您的情况下,您希望找到 Users->find('list') 并将其分配给您的控制器中的一个变量,然后在您的视图中显示 id 的位置,您在 id 上添加该新变量。

例如将 $job['Comment']['user_id'] 更改为 $users[$job['Comment']['user_id']]

【讨论】:

  • 但是,您必须在没有加载该模型的控制器内的模型上运行查找。如果您找到了加载该模型的好方法,请评论您是如何做到的。
  • 这对我有用。谢谢你。控制器:$this-&gt;set('users', $this-&gt;Job-&gt;User-&gt;find('list')); 然后在我看来:$users[$job['Comment']['user_id']];
  • 我不会选择这个解决方案,因为除了 Cake 为了获取关联所做的操作之外,还会运行另一个查询。因此产生的数据库负载是不必要的。 $displayField 是一个更“Caky”的解决方案,如另一条回复中所述,我的 cmets 将(希望)澄清您的所有问题。
【解决方案2】:

您可能忘记在 User 模型上设置 de displayField 属性。

class User extends AppModel { var $displayField = 'username';}

【讨论】:

  • 如果是这种情况,请记住,您必须重新创建视图才能使更改生效。
  • @Beto Frega:如何在不重新烘焙控制器的情况下重新烘焙视图(这实际上会删除您建议添加的内容)?
  • @linkyndy 我已经对视图本身进行了大量更改,所以我不想重新烘焙。这会对代码产生什么变化?我可以手动进行任何代码更改,以免打乱我的其他修改。
  • 没有必要。如果您没有修改生成的视图,重新烘焙会很有用。在这种情况下,将所有$comment['user_id'] 替换为$comment['User']['username']。另外,不要忘记在控制器中设置$this-&gt;Jobs-&gt;recursive = 2 以确保关联用户与评论一起被获取。通常,模型中的$displayField 属性设置视图中与该模型关联的可见字段。如果缺少该属性,则使用默认字段 (id)。
  • @linkyndy:您在那里发表的奇怪声明,因为在我的应用程序中我使用名称而不是用户名,这导致我的其他视图显示正确的名称(由于配置约定),除了视图.ctp 的相关模型即使使用递归 2 也无法检索到所需信息。您确定吗?
猜你喜欢
  • 1970-01-01
  • 2012-04-12
  • 2012-10-21
  • 1970-01-01
  • 2013-04-14
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多