Cakephp 使用模型别名时使用虚拟字段

Cakephp 使用模型别名时使用虚拟字段,cakephp,autocomplete,cakephp-2.0,Cakephp,Autocomplete,Cakephp 2.0,我是个新手。我一直在寻找这个问题的答案 在回答关于CakePHP()中自动完成的问题时,我遵循了RichardAtHome的指示 我在AppController中设置了该函数 这在实际字段中非常有效,但在使用虚拟字段时出现错误: class Person extends AppModel { public $virtualFields = array( 'name' => "CONCAT(Person.firstname, ' ', Person.lastname)

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

在回答关于CakePHP()中自动完成的问题时,我遵循了RichardAtHome的指示

我在AppController中设置了该函数

这在实际字段中非常有效,但在使用虚拟字段时出现错误:

class Person extends AppModel {
    public $virtualFields = array(
        'name' => "CONCAT(Person.firstname, ' ', Person.lastname)"
    );
}
我收到以下错误:
未找到列:“where子句”中的1054未知列“Person.name”

在检查SQL查询时,我看到:

(CONCAT(`Person`.`firstname`, ' ', `Person`.`lastname`)) AS `Person__name`
只有在使用
$model=$This->{$This->modelClass}->别名时,才会出现此问题。在特定控制器(不是AppController)中硬编码模型类可以很好地工作

我需要做什么才能让它工作

更新: 在摆弄它之后,我发现它与
$model=$this->{$this->modelClass}->alias没有关系完全正确

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

错误代码:

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

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

这是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;
    }

请显示实际触发错误的完整代码。另外,您是否确保
$model
实际包含预期值?请提及您的确切CakePHP版本!我认为你的阵列版本是错误的。应该是
$this->order[$this->别名前缀($key)]=$value。至少我经常使用的是:
public$order=array('username'=>'ASC')
@burzum I的理解可能有点慢,但这与所描述的问题有什么关系?我可能错了,但我认为更多的是在条件下使用虚拟场,至少从链接问题中的代码判断,问题可能是单个SQL片段,他需要使用
fragment=>value
表示法,以便CakePHP生成正确的查询,该查询使用虚拟字段SQL片段而不是
where
子句中的给定字段名(不确定这是CakePHP中的错误还是实际预期的行为)。这里还有第二个问题,因为您没有取消设置旧值(导致SQL异常)。可以在这里找到完整的解决方案: