2013-11-28 18 views
8

私はすでに存在するcakephp 1.3プロジェクトで作業しており、データベースに新しいテーブルを追加する必要がありました。私は私のコントローラでこれを持っている:CakePHP 1.3 - where句内の未知の列

$conditions = array('ShootingPlacement.person_id' => $id, 'Email.person_id' => $id, 'Email.shooting_placement_id' => 'ShootingPlacement.id'); 
    $shootingPlacements = $this->ShootingPlacement->find('all', compact('conditions')); 

そして、それは私にこのエラー与えている:

Warning (512): SQL Error: 1054: Unknown column 'Email.person_id' in 'where clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 684] 

そして、THSはそれを作成しようとしているクエリです:

SELECT `ShootingPlacement`.`id`, ... FROM `shooting_placements` AS `ShootingPlacement` 
LEFT JOIN `people` AS `Person` ON (`ShootingPlacement`.`person_id` = `Person`.`id`) 
LEFT JOIN `shootings` AS `Shooting` ON (`ShootingPlacement`.`shooting_id` = `Shooting`.`id`) 
WHERE `ShootingPlacement`.`person_id` = 123688 AND `Email`.`person_id` = 123688 AND `Email`.`shooting_placement_id` = 'ShootingPlacement.id' 
ORDER BY `lastname` ASC 

明らかに私のコントローラコードがされます間違っていますが、ShootingPlacementに電子メールテーブルを関連付ける方法がわかりません。私のモデルは正しいと思います。これまでのところ、私が持っている場合、これは:

$conditions = array('ShootingPlacement.person_id' => $id); 
    $shootingPlacements = $this->ShootingPlacement->find('all', compact('conditions')); 

それは射撃、ShootingPlacement人から行を取得します、私もそこにメールしたいです。電子メールにはShootinPlacementのものとPersonのものの2つの外部キーがあります。

これはモデルですが、私が作成したのは電子メールだけです。残りは正しく動作します。私は、ビュー上で必要なもの

class Email extends AppModel 
{ 
    var $name = 'Email'; 


    var $belongsTo = array 
    (
     'Person' => array 
     (
      'className' => 'Person', 
      'foreignKey' => 'person_id' 
     ), 
     'ShootingPlacement' => array 
     (
      'className' => 'ShootingPlacement', 
      'foreignKey' => 'shooting_placement_id' 
     ) 
    ); 
} 

class ShootingPlacement extends AppModel 
{ 
    var $name = 'ShootingPlacement'; 


    var $belongsTo = array 
    (
     'Person' => array 
     (
      'className' => 'Person', 
      'foreignKey' => 'person_id', 
      'order' => 'lastname ASC' 
     ), 
     'Shooting' => array 
     (
      'className' => 'Shooting', 
      'foreignKey' => 'shooting_id' 
     ) 
    ); 
} 

class Person extends AppModel 
{ 
    var $name = 'Person'; 

    var $belongsTo = array 
    (
     'PersonOrigin' => array 
     (
      'className' => 'PersonOrigin', 
      'foreignKey' => 'person_origin_id' 
     ) 
    ); 

    var $hasMany = array 
    (
     'ShootingPlacement' => array 
     (
      'className' => 'ShootingPlacement', 
      'foreignKey' => 'person_id', 
      'dependent' => false 
     ) 
    ); 
} 
class Shooting extends AppModel 
{ 
    var $name = 'Shooting'; 

    var $belongsTo = array 
    (
     'ShootingLocation' => array 
     (
      'className' => 'ShootingLocation', 
      'foreignKey' => 'shooting_location_id' 
     ), 
     'Emission' => array 
     (
      'className' => 'Emission', 
      'foreignKey' => 'emission_id' 
     ) 
    ); 
} 

はShootingPlacement変数をループしていると私はそれがShootingPlacementと人のその特定のIDのメール・テーブル・データを格納する必要があります(クエリで見たよう、人とShootingPlacementがありますすでに関係で、私はあまりにもメールがあることが必要)

答えて

3

あなたはあなたが後にしている関係に非常に注意する必要があります。これらの回答の一部をすばやく見てみると、電子メールモデルへの参加をPersonモデルに追加し、検索の条件に依存してクエリがサーバーのメモリを浪費しないようにすることを示唆しているようです。

まず、この電子メールの関係をPersonのすべてのクエリで暗黙的に指定したいと思っています。そうでなければ、を指定して、それぞれのクエリの結合を指定することができます。この場合は、間違いなくmodel relationshipsを使用してリンクしてください。

あなたのコードは、ShootingとShootingPlacement(これはモデルとモデルの関係をモデルにしていると仮定します)が2つのモデルに属していることを示しています。ちなみに、シュートbelongsToエミッション - 私たちはまだここには見ていない。私はこれが現在のシナリオには適用されないと仮定します。

それでは、あなたの電子メールのテーブルは、外部キーを持っているので、それはむしろhasManyより、hasOne関係になることを悪いをオフとしましょう - それはあなたがすることによって、それをリンクするために必要なものですので。これをShootingPlacementモデルにリンクする予定です。これはクエリしているモデルなので、モデルの周りにモデルが結合されている中心点にする必要があります。構造は賢明です。すべてがあなたのPersonモデルから生じるように思われるので、その代わりにというモデルをクエリする必要があります。しかし、これまでセットアップされている方法では、ほぼどこからでもクエリを実行でき、ほとんど同じ結果バーにいくつかのモデル名とテーブルエイリアスを取得することができます。

電子メールとShootingPlacementの間の外部キーが別の名前であり、CakePHP 1.3がこれをうまく処理しないため、外部キーを使用せず、代わりに外部キーを使用することをお勧めします。関係は条件となります。

class ShootingPlacement extends AppModel 
{ 
    var $name = 'ShootingPlacement'; 
    var $actsAs = array('Containable'); 

    var $hasOne = array(
     'Email' => array(
      'className' => 'Email', 
      'foreignKey' => false, 
      'conditions' => array(
       'Email.shooting_placement_id = ShootingPlacement.id', 
       'Email.person_id = ShootingPlacement.person_id' 
      ) 
     ) 
    ); 

    var $belongsTo = array (
     'Person' => array (
      'className' => 'Person', 
      'foreignKey' => 'person_id', 
      'order' => 'lastname ASC' 
     ), 
     'Shooting' => array (
      'className' => 'Shooting', 
      'foreignKey' => 'shooting_id' 
     ) 
    ); 
} 

私はまたそこに封じ込める行動を加えました。これにより、関連するモデルをプライマリモデルの結果と一緒に返す各クエリから制御することができます。これはデフォルトにallが設定されますが、特定のものやメモリの理由だけが必要な場合に便利です(これらの種類のクエリは、制限しないか、必要なフィールド名のみを指定すると、戻る)。

あなたのメールモデルを作成するときに、もうこのモデルをShootingPlacementに再度リンクすることで、このエンタングルモデルの混乱を複雑にすることはお勧めしません。あなたが言ったように、それはまた、Personモデルへの外部キーを持っています。だから、Personモデル(Personの外部キーを反映するために条件を変更する)と全く同じことをしたいかもしれません。これにより、モデルの柔軟性が少し向上します。 ShootingPlacement Personに参加し、必要に応じて別の関連モデルを使用せずに別個に照会することもできます。

Documentation

See also

+0

説明とリンクをお寄せいただきありがとうございます。 –

-1

これは必要なを提供する加入:

$conditions = array('ShootingPlacement.person_id' => $id, 'Email.person_id' => $id, 'Email.shooting_placement_id' => 'ShootingPlacement.id'); 

$joins = array(
    array(
    'table' => 'emails', 
    'alias' => 'Email', 
    'type' => 'LEFT', 
    'conditions' => array('Email.shooting_placement_id = ShootingPlacement.id') 
) 
); 



$shootingPlacements = $this->ShootingPlacement->find('all', 
    array(
     'conditions' => $conditions, 
     'joins' => $joins 
    ) 
); 
+0

-1、これは、この特定のインスタンスの修正が、underlを解決しませんyingの問題。モデルの関係を参照してください。 –

1

あなたはそれを呼び出すいると、「電子メール」であなたのモデルShootingPlacementをリンクする必要があります。

class ShootingPlacement extends AppModel 

var $name = 'Shooting'; 

var $hasMany= array 
(
    'Email' => array 
    (
     'className' => 'Email', 
     'foreignKey' => 'yourfk' 
    ), 
    ); 
} 

そして非常に強力なContainableBehaviorを使用します。

exemple:あなたのモデルで

$contain=array('Email'=>array('fields'=>array('id','...'))); 
$conditions=array('ShootingPlacement.id'=>$yourId); 
$this->ShootingPlacement->attachBehaviros('Containable'); 
$this->ShootingPlacement->find('all',$conditions);// your will retrieve yoru SHootingItem + Emails linked 
1

ちょうどあなたのコントローラで、以下のコードを書く

class Email extends AppModel { 
    var $name = 'Email'; 

    var $actsAs = array('Containable'); 

    var $belongsTo = array 
    (
     'Person' => array 
     (
      'className' => 'Person', 
      'foreignKey' => 'person_id' 
     ), 
     'ShootingPlacement' => array 
     (
      'className' => 'ShootingPlacement', 
      'foreignKey' => 'shooting_placement_id' 
     ) 
    ); 
} 

収容可能振る舞いを追加します。

$this->ShootingPlacement->recursive = 2; 
$this->ShootingPlacement->contain = array(
    'Shooting', 
    'Person' => array(
     'Email' 
    ) 
); 
$conditions = array(
    'ShootingPlacement.person_id' => $id, 
    'Email.shooting_placement_id' => 'ShootingPlacement.id' 
); 
$shootingPlacements = $this->ShootingPlacement->find('all', compact('conditions')); 

希望します。

1

はその後

$this->ShootingPlacement->recursive = 2; 

OR あなたは、単に電子メールのモデルに参加するCakePHPでは結合を使用することができますを追加するなどの

var $hasOne = array(
    'Email' => array(
      'className' => 'Email', 
      'foreignKey' => 'person_id' // Column defined for person ids in Email table 
      ) 
); 

下記のメールでのPersonモデルへの$ hasOneの関係を追加します。お問い合わせcakephp joining tables

関連する問題