4

投稿とトピックを保存し、Topic_Posts テーブルを使用してそれらを結合するアプリケーションがあります。

アプリケーションの関連付けは次のとおりです。

Post.php
class Post extends AppModel
{
    public $name = 'Post';

    public $belongsTo = 'User';

    public $hasMany = array('Answer');

    // Has many topics that belong to topic post join table... jazz
    public $hasAndBelongsToMany = array(
        'Topic' => array('with' => 'TopicPost')
    );
}

Topic.php
class Topic extends AppModel
{
    public $hasMany = array(
        'TopicPost'
    );
}

TopicPost.php
class TopicPost extends AppModel {
    public $belongsTo = array(
        'Topic', 'Post'
    );
}

ユーザーがトピックを表示すると、たとえば/topics/view/topicname、そのトピックを含むすべての投稿を表示したいとします。

これまでのところ、ビューの TopicsController に次のメソッドがあります。

public function view ( $slug )
{
    $topic = $this->Topic->find('first', array('conditions'=>array('Topic.slug'=>$slug)));
    $this->set('topic', $topic);
    $this->set('title_for_layout', $topic['Topic']['title'] . ' – Topics');

    $this->paginate = array
    (
        'Post' => array
        (
            'limit'=>15,
            'conditions'=>array
            (
                'Post.status'=>array(1,2),
                'TopicPost.topic_id' => $topic['Topic']['id'],
            ),
            'order'=>array('Post.datetime'=>'desc'),
            'contain'=>array('User'=>'Profile', 'TopicPost')
        )
    );

    $posts = $this->paginate('Post'); // this one

    $this->set('posts', $posts);

}

Posts と TopicPosts を使用できるようpublic $uses = array('Topic','TopicPost','Post');に、コントローラーの上部に以下を追加し、すべてのモデルを包含可能として機能させました。

したがって、基本的には、データベース モデル TopicPosts で、表示しているトピックの ID と一致する投稿を見つける必要があります。

4

3 に答える 3

1

モデルの関係に問題があると思います。モデル自体で実際にこれをエミュレートしているときに( Has-many-throughメソッドを使用して)、投稿モデルでHABTM関係がある理由がわかりませんTopicPost。ケーキに組み込まれているHABTMの動作を使用したくない場合(そして私があなたを責めない場合)、次のような関係を設定する必要があります。

class PostTopic extends AppModel { // note PostTopic, name should be alphabetical
    public $belongsTo = array('Post', 'Topic');
}

class Post extends AppModel {
    public $hasMany = array('PostTopic');
}

class Topic extends AppModel {
    public $hasMany = array('PostTopic');
}

次に、関連する投稿またはトピックのIDを取得するには、PostTopicクラスをロードして検索を実行するだけです。

// ie in Post Controller
$this->paginate($this->Post->PostTopic, array('PostTopic.topic_id' => $post['PostTopic']['topic_id']));

私のサイトにも同様の設定があり、ユーザーは製品を在庫に追加できます。これは一種のHABTM関係ですが、より多くのデータが添付されています。より複雑な例については、こちらの製品、在庫、ユーザーのモデルをご覧ください。

于 2012-04-23T12:05:26.580 に答える
0

質問コメントより:

また、TopicPostを使用して投稿のトピックをうまくプルできるため、DB構造と関係が正常に機能することに注意してください。動作していないように見えるトピックの投稿を取得しているだけです...

そうです、Post->Topic にはHABTMをセットアップしましたが、Topic->Post には HABTM をセットアップしなかったからです。2.0 の本では、ユース ケースを説明するために、あなたと同じように (ただし、レシピと材料を使用して) 例を定義しています。

hasMany と HABTM の主な違いは、HA​​BTM のモデル間のリンクが排他的ではないことです。たとえば、HABTM を使用して Recipe モデルを Ingredient モデルと結合しようとしています。おばあちゃんのスパゲッティ レシピの材料としてトマトを使用しても、材料を「使い切る」わけではありません。サラダレシピにも使えます。

(タグ/カテゴリのあなたの名前)をPost使用する場合も同じことが言えます。Topicそして彼らの例のように:

Ingredient モデルを使用しているときに Recipe データを取得したい場合は、Ingredient モデルで HABTM 関連付けを定義することを忘れないでください。

または、あなたの場合はトピックモデルです。

したがって、使用する必要があるモデルは次のとおりです。

class Post extends AppModel
{
    public $name = 'Post';

    public $belongsTo = 'User';

    public $hasMany = array('Answer');

    // Has many topics that belong to topic post join table... jazz
    public $hasAndBelongsToMany = array(
        'Topic' => array('with' => 'TopicPost')
    );
}

class Topic extends AppModel
{
    // Has many posts that belong to topic post join table... jazz
    public $hasAndBelongsToMany = array(
        'Post' => array('with' => 'TopicPost')
    );
}

さて、特別なことをしない限り特に必要ありませんがTopicPost、そのままで結構です。そして、そのモデルを使用してTopics を投稿に追加する (またはその逆) ことができますが、HABTM 保存を処理する組み込みメソッドを使用することをお勧めします。HABTMの保存の詳細については、このページを参照してください。

削除する場合は、ドキュメントに従って各モデルの HABTM オプションの結合テーブルと条件を定義してください。

于 2012-04-23T17:38:17.247 に答える