4

この質問はたくさんポップアップするようですが、どの答えも私の問題を解決するのに役立ちませんでした。

概要

  • 私はYiiを使用してアプリケーションを作成しています。
  • 3つのテーブルがあり、そのうちの2つで結合とフィルター処理を実行しようとしています。
  • CDbCriteriaとCActiveDataProviderを使用して結合とフィルタリングを実行しようとしています。
  • すべてのテーブルのモデルがありますが、それらを結合しようとするとSQLエラーが発生します。

テーブル

データベースUML

結合してフィルタリングするテーブルのモデルを作成しました。

記録

class Record extends CActiveRecord {
    public $owner;
    ...
    public function rules() {
        return array(
            array('given_name, family_name, dob, gender', 'required'),
            array('qr_id, site_id', 'numerical', 'integerOnly' => true),
            array('given_name, family_name, madin_name', 'length', 'max' => 100),
            array('country_of_birth, country_of_death, title', 'length', 'max' => 45),
            array('gender', 'length', 'max' => 5),
            array('dod, profile, epitaph', 'safe'),
            array('id, qr_id, given_name, family_name, madin_name, dob, dod, country_of_birth, country_of_death, gender, owner', 'safe', 'on' => 'search'),
    );
}

    ...
    public function relations() {
        return array(
            'families_left'  => array(self::HAS_MANY, 'Family', 'record_left_id'),
            'families_right' => array(self::HAS_MANY, 'Family', 'record_right_id'),
            'headstones'     => array(self::HAS_MANY, 'Headstone', 'record_id'),
            'other_names'     => array(self::HAS_MANY, 'OtherName', 'record_id'),
            'users'          => array(self::MANY_MANY, 'Users', 'record_owner(record_id, user_id)'),
            'record_owner'   => array(self::HAS_MANY, 'RecordOwner', 'record_id'),
        );
    }
    ...
}

RecordOwner

class RecordOwner extends CActiveRecord {
    ...
    public function relations() {
        // NOTE: you may need to adjust the relation name and the related
        // class name for the relations automatically generated below.
        return array();
    }
    ...
}

問題

CDbCriteriaにrecord_ownerの条件を追加して検索を更新しました。record_owner.user_idの比較を追加しましたが、SQLエラーが発生します。

探す()

public function search() {
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.

    $criteria = new CDbCriteria;

    $criteria->compare('id', $this->id);
    $criteria->compare('qr_id', $this->qr_id);
    $criteria->compare('given_name', $this->given_name, true);
    $criteria->compare('family_name', $this->family_name, true);
    $criteria->compare('madin_name', $this->madin_name, true);
    $criteria->compare('dob', $this->dob, true);
    $criteria->compare('dod', $this->dod, true);
    $criteria->compare('country_of_birth', $this->country_of_birth, true);
    $criteria->compare('country_of_death', $this->country_of_death, true);
    $criteria->compare('gender', $this->gender, true);
    $criteria->compare('title', $this->title, true);

    $criteria->with = array('record_owner');
    $criteria->compare( 'record_owner.user_id', $this->owner, true );

    return new CActiveDataProvider(
        $this,
        array(
             'criteria'   => $criteria,
             'pagination' => array(
                 'pageSize' => Yii::app()->params['pageSize'],
             )
        )
    );
}

SQLエラー

CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'record_owner.user_id' in 'where clause'. The SQL statement executed was: SELECT `t`.`id` AS `t0_c0`, `t`.`qr_id` AS `t0_c1`, `t`.`given_name` AS `t0_c2`, `t`.`family_name` AS `t0_c3`, `t`.`madin_name` AS `t0_c4`, `t`.`dob` AS `t0_c5`, `t`.`dod` AS `t0_c6`, `t`.`country_of_birth` AS `t0_c7`, `t`.`country_of_death` AS `t0_c8`, `t`.`gender` AS `t0_c9`, `t`.`profile` AS `t0_c10`, `t`.`epitaph` AS `t0_c11`, `t`.`site_id` AS `t0_c12`, `t`.`title` AS `t0_c13` FROM `record` `t` WHERE (record_owner.user_id LIKE :ycp0) ORDER BY `t`.`given_name` LIMIT 25 

質問

この結合とフィルターをどのように行う必要がありますか?

4

2 に答える 2

4

メソッドに追加$criteria->together = true;searchます。

説明のためにこれを見てください:

http://www.yiiframework.com/doc/api/1.1/CDbCriteria#together-detail

特に、

このプロパティが設定されていない場合、プライマリテーブルが制限またはページ分割されていると、HAS_MANYリレーションごとにSQLステートメントが実行されます。それ以外の場合は、すべてに対して1つのSQLステートメントが実行されます。

この値を設定しておらず、ページネーションを使用していrecord_ownerたため、リーチ結果に対する別のクエリによってsが取得されていました。もちろん、クエリが実際に終了したと仮定します。

設定することにより$criteria->together = true;、作成されたクエリを強制的に単一のクエリにします。これは、テーブル結合を実行することによって実行されます。これは、関連するテーブルの列の1つでクエリをフィルタリングするために必要なものです。

于 2013-02-15T03:42:42.517 に答える
2

ウィレムによって提案された解決策。1行の修正でした。

$ criteria-> together=true;を追加します。search()メソッドに。

public function search() {
    // Warning: Please modify the following code to remove attributes that
    // should not be searched.

    $criteria = new CDbCriteria;

    $criteria->compare('id', $this->id);
    $criteria->compare('qr_id', $this->qr_id);
    $criteria->compare('given_name', $this->given_name, true);
    $criteria->compare('family_name', $this->family_name, true);
    $criteria->compare('madin_name', $this->madin_name, true);
    $criteria->compare('dob', $this->dob, true);
    $criteria->compare('dod', $this->dod, true);
    $criteria->compare('country_of_birth', $this->country_of_birth, true);
    $criteria->compare('country_of_death', $this->country_of_death, true);
    $criteria->compare('gender', $this->gender, true);
    $criteria->compare('title', $this->title, true);

    $criteria->with = array('record_owner');
    $criteria->compare( 'record_owner.user_id', $this->owner, true );
    $criteria->together = true;

    return new CActiveDataProvider(
        $this,
        array(
             'criteria'   => $criteria,
             'pagination' => array(
                 'pageSize' => Yii::app()->params['pageSize'],
             )
        )
    );
}
于 2013-02-15T02:29:48.947 に答える