1

特定のタグまたはタグを持つ投稿のページネーションを使用して検索を実行しようとしています (たとえば、ユーザーが 2 つのタグを選択すると、いずれかのタグを含む投稿が返されます)。

Posts テーブルで定義された関係があります

public $hasAndBelongsToMany = array('Tags' => array(
            'className'              => 'Tags',
            'joinTable'              => 'posts_tags',
            'foreignKey'             => 'post_id',
            'associationForeignKey'  => 'tag_id',
            'unique'                 => 'keepExisting'));

Find を使用して特定のタグを持つ行を取得するにはどうすればよいですか (名前または ID で問題ありません)

しようとしている:

// other pagination settings goes here
$this->paginate['conditions']['Tags.id'] = 13;

関係が存在しないというエラーが表示されます。

デバッグ情報を見ると、テーブルが Posts_Tags および Tags テーブルに参加していないように見えますが、データをデバッグしてビューに表示すると、Posts オブジェクトにタグ データが含まれています。

これについて私が見つけることができるドキュメントのほとんどは、CakePHP の以前のバージョンを中心に展開しているようです。

4

2 に答える 2

3

満足のいく解決策を自分で見つけることができませんでした。これを処理するためのビヘイビアーを作成しました。

HabtmBehavior.phpというファイルを作成し、app / Model/Behaviorフォルダーに配置します。そこにコードのブロックを置き、ファイルを保存します。

モデルに動作を追加します。例:public $ actsAs = array('Habtm');

これがfindの使用例です。

<?php $this->Entry->find('all', array('habtm'=>array('Tag'=>array('Tag.title'=>'value to find'))) ?>

Paginateは次のようになります。

$this->paginate['Entry']['habtm']['Tag'] = array('Tag.title'=>'value to find');

habtm配列にモデル名を追加することで、必要な数のリレーションを自由に追加できます。(複雑にならないように注意してください。検索結果が遅くなる可能性があります。)

<?php
class HabtmBehavior extends ModelBehavior {

    public function beforeFind(Model $model, $options) {
    if (!isset($options['joins'])) {
      $options['joins'] = array();
    }
    if (!isset($options['habtm'])) {
      return $options;
    }
    $habtm = $options['habtm'];
    unset($options['habtm']);

    foreach($habtm as $m => $scope){
      $assoc = $model->hasAndBelongsToMany[$m];
      $bind = "{$assoc['with']}.{$assoc['foreignKey']} = {$model->alias}.{$model->primaryKey}";

      $options['joins'][] = array(
          'table' => $assoc['joinTable'],
          'alias' => $assoc['with'],
          'type' => 'inner',
          'foreignKey' => false,
          'conditions'=> array($bind)
      );

      $bind = $m.'.'.$model->{$m}->primaryKey.' = ';
      $bind .= "{$assoc['with']}.{$assoc['associationForeignKey']}";

      $options['joins'][] = array(
          'table' => $model->{$m}->table,
          'alias' => $m,
          'type' => 'inner',
          'foreignKey' => false,
          'conditions'=> array($bind) + (array)$scope,
      );
    }
    return $options;
    }

}

お役に立てれば。ハッピーベーキング。

于 2013-03-09T22:51:17.103 に答える
1

最善の解決策は、結合テーブルモデルに検索機能を適用することだと思います。以前にこれを試してみましたが、うまくいきました。

PostTag モデルで:

/**
 * @see Model::$actsAs
 */
    public $actsAs = array(
        'Containable',
    );

/**
 * @see Model::$belongsTo
 */
    public $belongsTo = array(
        'Post' => array(
            'className' => 'Post',
            'foreignKey' => 'post_id',
        ),
        'Tags' => array(
            'className' => 'Tag',
            'foreignKey' => 'tag_id',
        ),
    );

あなたのコントローラーで:

   // $tagsId = tags ids
    $posts = $this->PostTag->find('all', array('conditions' => array('PostTag.tag_id' => $tagsId),'contain' => array('Post')));

タグ(複数)、post_tags(最初の単数、2番目の複数)、post(複数)テーブルがある場合は、Tag、PostTag、Postモデルが必要です。

于 2012-08-28T07:34:56.187 に答える