0

我是 CakePHP 新手。我一直在寻找这个问题的答案一段时间。

我按照 RichardAtHome 的指示回答了关于 CakePHP 中的自动完成功能(autoComplete CakePHP 2.0)。

我在我的 AppController 中设置了该功能。

这对真实字段非常有效,但在使用虚拟字段时会出现问题:

class Person extends AppModel {
    public $virtualFields = array(
        'name' => "CONCAT(Person.firstname, ' ', Person.lastname)"
    );
}

我收到此错误:Column not found: 1054 Unknown column 'Person.name' in 'where clause'

检查 SQL 查询时,我看到:

(CONCAT(`Person`.`firstname`, ' ', `Person`.`lastname`)) AS `Person__name`

此问题仅在我使用$model = $this->{$this->modelClass}->alias;. 在特定控制器(不是 AppController)中硬编码模型类可以正常工作。

我需要做什么才能使其工作?

更新:

在摆弄这个之后,我发现它根本不相关$model = $this->{$this->modelClass}->alias;

相反,我更改了方法'conditions'中的值,find()结果一切正常。我仍然对为什么感到困惑,但现在它工作得很好。

不正确的代码:

$result = $this->$model->find('all', array(
    'conditions' => array(
        $model . '.' . $field . " LIKE '%" . $term . "%'"
    )
));

正确代码:

$result = $this->$model->find('all', array(
    'conditions' => array(
        $model . '.' . $field . " LIKE " => "%" . $term . "%"
    )
));
4

1 回答 1

0

那是 CakePHP 核心的问题。您不能在属性声明中使用变量或其他属性。所以你必须重写构造函数并使用 $this->alias 设置你的虚拟字段。核心没有自动的方法在内部处理这个,所以你必须照顾它。

顺便说一下,这个问题适用于所有模型属性。我们对模型的 $order 属性也有同样的问题。我将在此处粘贴代码,但您必须修改 aliasPrefixing() 方法以不只是通过字符串的开头。用正则表达式替换它,您应该可以将前缀替换方法应用于所有属性。

/**
 * Constructor
 *
 * @param integer|string|array $id Set this ID for this model on startup, can also be an array of options, see above.
 * @param string $table Name of database table to use.
 * @param string $ds DataSource connection name.
 */
   public function __construct($id = false, $table = null, $ds = null) {
        parent::__construct($id, $table, $ds);
       $this->prefixOrderProperty();
    }

/**
 * Prefixes the order property with the actual alias if its a string or array
 *
 * The core fails on using the proper prefix when building the query with two
 * different tables. Already reported this to the core team and might work on a
 * core patch to fix this in the DboSource. The core fix should be done in DboSource,
 * when reading the order property from the model.
 *
 * @return void
 */
    public function prefixOrderProperty() {
        if (is_string($this->order)) {
            $this->order = $this->aliasPrefixing($this->order);
        }
        if (is_array($this->order)) {
            foreach ($this->order as $key => $value) {
                $this->order[$key] = $this->aliasPrefixing($value);
            }
        }
    }

/**
 * Checks if a string of a field name contains a dot if not it will add it and add the alias prefix
 *
 * @param string
 * @return string
 */
    public function aliasPrefixing($string) {
        if (stripos($string, '.') === false) {
            return $this->alias . '.' . $string;
        }
        return $string;
    }
于 2013-08-13T10:48:44.290 回答