【问题标题】:cakePHP - adding new functionality to the model or controllercakePHP - 向模型或控制器添加新功能
【发布时间】:2011-06-12 14:17:45
【问题描述】:

我是 cakePHP 和 MVC 开发的新手,并试图用 cakePHP 创建一些东西,但不知道如何做到这一点:

我正在创建一个简单的 CRUD 应用程序,它通过简单的数据输入表单接收专辑和歌曲。我创建了数据库并使用 Cake 控制台应用程序来创建所有模型/控制器等,它运行良好。我可以对专辑和歌曲进行 CRUD 没问题,并且数据库中的歌曲表通过外键连接到专辑表,因此所有链接和关联都在模型中。

我想要做的是能够单击专辑并查看与该专辑相关的歌曲,但我不知道该怎么做。我是否需要在模型中添加查询,或者该功能是否进入 Controller ?

我的看法是:在专辑列表中制作专辑名称链接,这称为 |viewAlbum|在歌曲控制器中使用专辑 ID 函数。虽然不知道从这里去哪里......

谁能指出我正确的方向?

干杯, 科尔姆


@JohnP 感谢您的回复。您如何创建链接以在控制器中调用该函数?我有:

echo $html->link(__($album['Album']['title'], true), array('controller'=>'Songs', 'action'=>'viewAlbum', $album['Album']['id']));

其中 viewAlbum 是歌曲控制器中函数的名称。关于为什么这不起作用的任何想法?

【问题讨论】:

    标签: php cakephp


    【解决方案1】:

    原型 -

    如果我理解正确 - 您使用的是 John 的示例,并且您需要修复视图中调用他的控制器的链接?

    <?
    echo $this->Html->link(__($album['Album']['title'], true), array('controller'=>'Album', 'action'=>'viewSongs', $id));
    
    ?>
    

    John 的示例解释了如何在 Albums 控制器 中创建一个方法,建议在 Songs 模型 中点击一个返回所需结果的方法。

    因此您的链接将针对专辑控制器,其操作应该是控制器方法。

    此方法在 Songs 控制器中意义不大,因为它需要 专辑 ID。您只希望专辑控制器从 Songs 模型/表中提取相关数据。约翰的回答是完全正确的,但如果你刚刚开始使用 Cake,可能太复杂了。 John 通过在 Song 模型 中放置一个方法来拆分所需的功能,该方法由 Albums 控制器 中的方法调用,该方法会拉取结果以供您的视图显示。

    我将其切换为“胖控制器”,这对于短代码更容易理解,但 MVC 更少。

    您需要从专辑到歌曲的 hasMany 关系 - 每个专辑都有很多歌曲:

    // ../models/album.php
    
    class Album extends AppModel {
    
        var $name = 'Album';
    
        var $hasMany = array(
            'Song' => array(
                'className' => 'Song',
                'foreignKey' => 'album_id'
            )
        );
    

    您的控制器操作将如下所示:

    // ../controllers/albums_controller.php
    
    function viewSongs($id = null) {
        if(isset($id) && $id != null) {
            $albums = $this->Album->find('first',       
                array('conditions'=>array('Album.id'=>$id));
            $songs = $this->Album->Song->find('all', 
                array('conditions'=>array('Song.album_id'=>$id)));
            // This returns variables to the view to use
            $this->set(compact('albums', 'songs'));
        }
    }
    

    您的视图将被称为 viewSongs.ctp,它看起来像这样:

    // ../views/albums/viewSongs.ctp
    
    <?php 
    foreach($albums as $album) {
        echo "<h2>{$album['name']}</h2>";
        echo "<ul>";
        foreach ($songs as $song) {
           echo "<li>{$song['Song']['name']}</li>"
        }
        echo "</ul>";
    }
    

    您在 ../views/albums/view.ctp 中的链接如下:

    <?php
    echo $this->Html->link('View Songs', array('controller'=>'albums',
        'action'=>'viewSongs', $id));
    ?>
    

    【讨论】:

    • 感谢您的详细回复。我假设因为我正在寻找的内容与歌曲模型的索引视图基本相同,但经过过滤后仅显示一张我将通过歌曲控制器进行的专辑。从那以后我就没有机会看这个了,但是当我这样做时,我会尝试这种方式,并会回来让你知道我的进展情况并过滤你的答案。
    【解决方案2】:

    Cake 的原生 ORM 已经为您完成了这项工作。如果您实际上进入专辑的查看页面,它应该会向您显示所有相关的歌曲。这仅在您正确设置关系时才有效。

    如果您想自己编写此行为的代码,您可以在 AlbumController 中添加 viewSongs 操作。此方法将查看传递给它的专辑 ID,并在您的 Song 模型中调用一个方法(例如 getSongsByAlbum($aid))。在您的歌曲模型中的该方法内部将是一个看起来像

    的调用
    $opts = array(
       'conditions' => array(
           'album_id' => $aid
       )
    );
    return $this->find('all', $opts);
    

    【讨论】:

    • 和@satyrwilder。谢谢你的帮助。我让它在专辑控制器中使用新的 viewSongs 动作。我的模型已经从烘焙应用程序中获得了 hasMany 关系。有一件事让我抓狂了一阵子,视图需要被称为 view_songs.ctp - 而不是 viewSongs.ctp。该死的 cakePHP 约定!
    • @Protos,在您添加此评论之前,实际上并没有注意到您的跟进。您只能在 cmets 中用 @ 标记人,而不是答案部分 :) 乐于助人
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多