2

我有一个 cakephp 设置来管理多个网站,其中有许多常见的模型,表前缀为“main_”。并且有一个常见的模型 Fbuser 正在使用表'main_fb_users'

现在,我有一个网站,它的表前缀是“myweb_”,我有一个模型 Mymodel,它必须与 Fbuser 左连接。

$this->Mymodel->find('all', array(
'joins' => array(
'table' => 'main_fb_users',
'alias' => 'Fbuser',
'type' => 'LEFT',
'conditions' => array('Mymodel.field01 = Fbuser.field02')
));

这是我收到的错误消息

SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dbserver.myweb_main_fb_users' doesn't exist

显然,这是由于表前缀的不同,我无法更改database.php中设置的默认表前缀。

那么如何覆盖连接查询中的表前缀呢?

4

3 回答 3

3

将模型对象而不是表名作为字符串传递:

$this->Mymodel->find('all', array(
'joins' => array(
'table' => $this->Mymodel->FbUser,
'alias' => 'Fbuser',
'type' => 'LEFT',
'conditions' => array('Mymodel.field01 = Fbuser.field02')
));

似乎对我有用。

于 2015-10-07T09:52:35.113 回答
1

被黑方法(适用于 2.x 版)

转到 - /lib/Cake/Model/Datasource/DboSource.php 行 #942

修改函数 fullTableName 如下:

    公共函数 fullTableName($model, $quote = true, $schema = true, $prefix = true) {
            if (is_object($model)) {
                $schemaName = $model->schemaName;
                $table = $model->tablePrefix 。$模型->表;
            } elseif (!empty($this->config['prefix']) && strpos($model, $this->config['prefix']) !== 0) {
                $table = (((!empty($prefix) && $prefix !== true)?$prefix:(($prefix === false)?'':$this->config['prefix'] ))) . strval($模型);
            } 别的 {
                $table = strval($model);
            }

            if ($schema && !isset($schemaName)) {
                $schemaName = $this->getSchemaName();
            }

            如果($报价){
                if ($schema && !empty($schemaName)) {
                    if (strstr($table, '.') === false) {
                        返回 $this->name($schemaName) 。'。' . $this->name($table);
                    }
                }
                返回 $this->name($table);
            }

            if ($schema && !empty($schemaName)) {
                if (strstr($table, '.') === false) {
                    返回 $schemaName 。'。' . $表;
                }
            }

            返回$表;
        }

现在转到同一页面上的第 1881 行并将函数 buildJoinStatement 修改为:

    公共函数 buildJoinStatement($join) {
            $data = array_merge(数组(
                '类型' => 空,
                '别名' => null,
                'table' => 'join_table',
                '条件' => '',
            ), $加入);

            if (!empty($data['alias'])) {
                $data['alias'] = $this->alias 。$this->name($data['alias']);
            }
            if (!empty($data['conditions'])) {
                $data['conditions'] = trim($this->conditions($data['conditions'], true, false));
            }
            if (!empty($data['table']) && (!is_string($data['table']) || strpos($data['table'], '(') !== 0)) {
                $data['table'] = (isset($data['prefix']))?$this->fullTableName($data['table'],true,true,$data['prefix']):$this ->fullTableName($data['table']);
            }
            返回 $this->renderJoinStatement($data);
        }

而已...

现在,如果您在 joins 数组中提供前缀元素,那么它将对该表使用相同的前缀。

例子

    '加入'=>数组(
        大批(
            '表'=>'GDN_Comment',
            '类型'=>'左',
            '前缀'=>假,
            '别名'=>'评论',
            '条件'=>数组('MyPost.DiscussionID = 2'),
        ),
    ),

然后它将在sql查询中使用“GDN_Comment as Comment”

或者

    '加入'=>数组(
        大批(
            '表'=>'GDN_Comment',
            '类型'=>'左',
            '前缀'=>'ds_',
            '别名'=>'评论',
            '条件'=>数组('MyPost.DiscussionID = 2'),
        ),
    ),

然后它将在sql查询中使用“ds_GDN_Comment as Comment”

于 2015-04-16T07:19:49.953 回答
0

您可以在控制器中动态调整表前缀:

$this->loadModel('MainFbUser');
$this->MainFbUser->tablePrefix = '';

在文档中:

http://book.cakephp.org/2.0/en/models/model-attributes.html#tableprefix

于 2013-05-15T10:44:55.867 回答