0

我有一张images桌子和一张servers桌子。images有一个字段,它是表中字段server_id的外键。该表还有一个名为 的字段,这是我要检索的。idserversserversname

这是我的控制器操作代码:

$images = $this->Image->find('all', array(
    'conditions' => array('Image.user_id' => $this->Auth->user('id')),
    'order' => array('Image.uploaded DESC')
));
$this->set('images', $images);

它得到这样的数据:

Array
(
    [0] => Array
        (
            [Image] => Array
                (
                    [id] => 103
                    [orig_name] => Untitled-5.jpg
                    [hash] => MnfWKk
                    [filename] => MnfWKk.jpg
                    [uploaded] => 2012-07-12 00:09:08
                    [views] => 0
                    [album_id] => 
                    [user_id] => 15
                    [server_id] => 1
                )

        )
)

而不是server_id,我想从表中获取name字段。servers我怎样才能调整我的find()方法来得到这个?我知道这是一个 SQL 连接,但我不知道如何告诉 Cake 做一个以获取服务器名称。

谢谢。

4

3 回答 3

1

TLDR:

设置正确的CakePHP 关联,并使用CakePHP 的 Containable。(使用递归-1)。

更长的描述:

最好将 find 代码保留在模型本身中,这就是我将展示的内容,但请随意(如果必须)将其移回控制器中。

这样做可以让您getImages()从任何控制器调用相同的函数,并根据您想要返回的内容传递不同的参数。像这样编码的好处是,你总是知道你是否正在寻找与查询/数据库相关的代码,你应该在模型中寻找。当下一个查看您的代码的人不必去搜索时,这是非常有益的。

由于图像和服务器之间建立了关联,因此您可以在查询图像时“包含”服务器信息。但是 - 你不能使用“包含”,直到你指定你想要你的模型$actAs = array('Containable');[ CakePHP 书:可容纳]

最后,在您的 AppModel 中,最好设置$recursive = -1;. 这使其默认适用-1于所有模型。如果出于某种原因您反对这样做,请确保在使用可包含的任何时候将递归设置为 -1。而且 - 一旦你学会使用可包含,你将永远不会回头 - 这太棒了。你可以做的事情还有很多

代码:

//AppModel *******
//...
$recursive = -1;
//...

//Images controller *******
//...
public function whatever() {
    $opts = array();
    $opts['user'] = $this->Auth->user('id');
    $images = $this->Image->getImages($opts);
    $this->set(compact('images'));
}
//...


//Image model *******
//...
public $actsAs = array('Containable');

public belongsTo = array('Server');

public function getImages($opts = array()) {

    $params = array('condtions'=>array());

    //specific user
    if(!empty($opts['user'])) {
        array_push($params['conditions'], array('Image.user_id'=>$opts['user']);
    }

    //order
    $params['order'] = 'Image.uploaded DESC';
    if(!empty($opts['order'])) {
        $params['opts'] = $opts['order'];
    }

    //contain
    $params['contain'] = array('Server');

    //returns the data to the controller
    return $this->find('all', $params);
}

其他一些注意事项

  • 您还应该在服务器模型中设置关联。
  • 我给出的代码示例写得相当冗长(这是一个词吗?)。随意压缩你认为合适的
  • 您还可以扩展模型的 getImages() 方法以接受更多参数,例如 find、limit...等。随心所欲地定制这个 - 这不是这样做的方式 - 就像我通常使用的一样。
  • 根据您的问题,如果您只需要一个字段,您可以在“包含”中指定您想要的字段 - 有关详细信息,请参阅本书。
  • 现在可能看起来很混乱,但是值得学习如何正确地做这些事情——它会让你的生活更轻松。
于 2012-07-12T00:34:57.880 回答
0

Cake 有很多模型关系来实现这一点。看看这个页面,我想你会使用 belongsTo 关系

于 2012-07-11T23:35:27.127 回答
0

初学者的简单替代方式

$images = $this->Image->find('all', array(
    'conditions' => array('Image.user_id' => $this->Auth->user('id')),
    'joins' => array(
                    array(
                        'table' => 'servers',
                        'alias' => 'Server',
                        'type' => 'inner',  //join of your choice left, right, or inner
                        'foreignKey' => true,
                        'conditions' => array('Image.server_id=Server.id')
                    ),
                ),
    'order' => array('Image.uploaded DESC')
));

这在性能上非常好

于 2013-10-22T13:50:48.750 回答