CakePHP2.2.3についてサポートが必要です。
私が持っているもの
現在、次の設定があります。
Post
多くを持っています Attachment
それは正常に動作し、ページは2つのクエリで生成されます。
SELECT *, `Post`.`id`
FROM `posts` AS `Post`
WHERE 1 = 1
ORDER BY `Post`.`created` DESC
SELECT
`Attachment`.`id`,
`Attachment`.`post_id`,
`Attachment`.`created`
FROM
`attachments` AS `Attachment`
WHERE
`Attachment`.`post_id` IN (1, 2, 3, ..., n)
欲しいもの
関係を次のように拡張したいと思います。
Post
hasMany Attachment
; すべてのAttachment
belongsTo Type
そして、CakePHPをそれに従わせるのが辛いのかわかりません。
基本的に、私が必要とするのは次のとおりです。
SELECT *, `Post`.`id`
FROM `posts` AS `Post`
WHERE 1 = 1
ORDER BY `Post`.`created` DESC
SELECT
`Attachment`.`id`,
`Attachment`.`post_id`,
`Attachment`.`created`,
`Type`.`title`, `Type`.`icon`
FROM
`attachments` AS `Attachment`
LEFT JOIN
`types` AS `Type`
ON (`Attachment`.`type_id`=`Type`.`id`)
WHERE
`Attachment`.`post_id` IN (1, 2, 3, ..., n)
LEFT JOIN types
追加されたことに注意してください。
したがって、2番目のクエリで対応する型データを取得します。ループ内または->query()
呼び出しを使用してデータを取得できることはわかっていますが、これを可能な限り効果的かつ柔軟にしたいと考えています。
問題
Containable、Model Unbindingトリック(およびこれ)を試しましたが、成功しませんでした。オプションのさまざまな組み合わせを試しましたが、結合も削除したと思います。これが私のPostsController
今の姿です。
class PostsController extends AppController {
public function index() {
$this->Post->unbindModel(array('hasMany' => array('Attachment')));
$this->Post->Attachment->unbindModel(array('belongsTo' => array('Type')));
$this->Post->bindModel(array(
'hasMany' => array(
'Attachment' => array(
'className' => 'Attachment',
// when uncommented, throws the "Unknown column Post.id" SQLSTATE error
// 'conditions' => array('Post.id' => 'Attachment.post_id'),
'foreignKey' => false,
),
),
));
$this->Post->Attachment->bindModel(array(
'belongsTo' => array(
'Filetype' => array(
'className' => 'Filetype',
// 'conditions' => array('Type.id' => 'Attachment.type_id'),
'foreignKey' => false,
),
),
));
$all = $this->Post->find('all', array(
'joins' => array(
array(
'table' => 'users',
'prefix' => '',
'alias' => 'User',
'type' => 'INNER',
'conditions' => array(
'User.id = Post.user_id',
)
),
),
'contain' => array('Attachment', 'Type'),
'conditions' => array(),
'fields' => array('*'),
'order' => 'Post.created ASC'
));
var_dump($all);exit;
}
}
ただし、ループ内の反復ごとに追加のクエリを実行し、すべての添付ファイルを取得します。
SELECT `Attachment`.`id`, ...
FROM `attachments` AS `Attachment`
WHERE 1 = 1
この関連付けの条件のコメントを解除すると、SQLSTATE「ColumnPost.idnotfounderror」がスローされます。ここに結合されたPostテーブルがないためだと思います。
これを設定するには手が必要です。
助けてください!ありがとう
アップデート
コントローラーを次のように変更しました。bindModel
/コードがないことに注意してくださいunbindModel
。関係はモデルクラスで設定されます(この場合は正しいですか?)。
class PostsController extends AppController {
public function index() {
$options = array(
'contain' => array(
'Post',
'Type'
),
'order' => 'Post.created DESC',
'conditions' => array(
// 'Post.title LIKE' => 'my post'
)
);
// The following throws "Fatal error: Call to a member function find() on a non-object"
// $posts = $this->Attachment->find('all', $options);
// So I had to use $this->Post->Attachment instead of $this->Attachment
$posts = $this->Post->Attachment->find('all', $options);
$this->set(compact('posts'));
}
}
これはAttachment
モデルです:
class Attachment extends AppModel {
public $belongsTo = array(
'Type' => array(
'className' => 'Type',
'foreignKey' => 'type_id',
),
'Post' => array(
'className' => 'Post',
'foreignKey' => 'post_id',
),
);
}
上記のコードはこのクエリを実行します:
SELECT
`Attachment`.`id`, `Attachment`.`type_id`, `Attachment`.`post_id`, `Attachment`.`created`,
`Type`.`id`, `Type`.`title`,
`Post`.`id`, `Post`.`text`, `Post`.`created`
FROM
`attachments` AS `Attachment`
LEFT JOIN `types` AS `Type` ON (`Attachment`.`type_id` = `Type`.`id`)
LEFT JOIN `posts` AS `Post` ON (`Attachment`.`post_id` = `Post`.`id`)
WHERE
1 = 1
ORDER BY
`Post`.`created` ASC
すべてはここの添付ファイルについてです。つまり、投稿は添付ファイルに結合されているため、投稿に添付ファイルがない場合は返されません。これはおそらくAttachment->find()
、添付ファイルの観点からの呼び出しであるためです。私はそれがちょうどあるべきだと思います:
// ...
FROM
`posts` AS `Post`
LEFT JOIN `attachments` AS `Attachment` ON (`Attachment`.`post_id` = `Post`.`id`)
LEFT JOIN `types` AS `Type` ON (`Attachment`.`type_id` = `Type`.`id`)
// ...
しかし、それはうまくいきませんね?、、がありますがposts
、それらには異なる関係タイプがあります。もともと、私はCakePHPが実行する2つの別々のクエリを投稿しました-それには理由があるに違いありません。attachments
types
UPDATE2
私はまだ、初期設定で2番目のクエリをモデルに変更することがすべてだと信じています( 「欲しいもの」Attachment
セクションを参照してください)。だから私は添付ファイル自体と一緒に添付ファイルの種類を取得します。その場合、テーブルをLEFT JOINすることで、データベース関係ロジックが壊れることはありませんね。1つの複雑な呼び出し
でそれを行う方法がないことを確認したいだけです。types
attachments
find()