3

私は常に、追加モデルのロードを適切に処理すると考えていたので、cakephp の包含可能な要素の大ファンです。しかし、ここ数日でさらに深く掘り下げたところ、実際にはメモリの問題があることがわかりました。

次のモデル構造を考えてください。

  • プロジェクトには多くの壁があります
  • プロジェクトには多くの参加者がいます
  • 壁にはたくさんのポストがあります
  • 投稿には多くのコメントがあります
  • 参加者の投稿数が多い
  • 参加者のコメントが多い
  • 参加者はユーザーに属します
  • 参加者はプロジェクトに所属しています

およびその逆

  • 投稿は参加者に属します
  • 投稿はウォールに属します
  • コメントは参加者のものです
  • コメントは投稿に属します
  • ユーザーには多くの参加者がいます

wall-Controller には、次の find-Statement があります。

$this->set(
  "posts", 
  $this->Post->find(
    "all", array(
      "conditions" => array("Post.wall_id" => $wall["Wall"]["id"]), 
      "contain" => array("Participant")
    )
  )
);

私は、cakephp がすべての投稿を見つけて、対応する参加者オブジェクトのみを含めることを期待しています。しかし、私が得るのは、すべての投稿 (正しい) とその参加者 (正しい) だけでなく、対応する壁 (正しくない) と対応するコメント (利用可能な場合) (正しくない) のリストです。したがって、パフォーマンスの観点からは、オブジェクトが多すぎるため、「致命的なエラー - メモリの過負荷」が発生する可能性があります。

そして、理論的に非常にセクシーで興味深い部分については、次のとおりです。

$this->set(
  "posts", 
  $this->Post->find(
    "all", array(
      "conditions" => array("Post.wall_id" => $wall["Wall"]["id"]), 
      "contain" => array("Participant.User")
    )
  )
);

Post とParticipant.Userオブジェクトのみに関心があるため、contain-array を Participant.User に変更します。しかし、ここでも、User オブジェクトだけでなく、Participant に関連する他のすべてのオブジェクト (プロジェクト、投稿、コメントなど) も取得しており、オブジェクト ツリーは以前よりもはるかに大きくなっています。

だから、これを実装する正しい方法は何だろうと思っていましたか?「結合」オプションを明示的に設定する必要がありますか、それともフィールド オプションを (ルートまたは含むオプションで) 設定する必要がありますか?

オーストリアからのご挨拶。

4

7 に答える 7

1
于 2012-01-13T00:46:46.837 に答える
0

ドット構文を使用したことはありません。試しましたか

"contain" => array('Participant'=>array('User'))

私にとっては、封じ込め可能な振る舞いもどういうわけか結びついていないように見えます。どのようにあなたの行動を結びつけ/活性化しましたか?

于 2011-11-15T12:24:27.773 に答える
0

私は同じ問題を解決してきましたが、一部のモデルで afterFind コールバックを設定し、別の SQL クエリ内で、包含可能な動作が混乱することがわかりました。したがって、コールバック内の内部クエリをプレーン SQL に書き直すことをお勧めします。これは私を助け、包含可能な連鎖を解決しました。

于 2012-01-12T20:41:47.387 に答える
0

これは役立つ傾向がありますか:

$this->loadModel('Participant');
                $this->Participant->bindModel(array(
                    'belongsTo' => array(
                        'User' => array(
                            'className' => 'Wish',
                            'foreignKey' => 'user_id'
                        )
                    )
                ),0);
$this->set(
  "投稿",
  $this->Post->find(
    "すべて"、配列(
      "条件" => array("Post.wall_id" => $wall["Wall"]["id"]),
      「含む」 => false
    )
  )
);
于 2011-11-15T12:05:45.640 に答える
0

プロジェクトの 1 つで ContainableBehaviour を使用していますが、多数の関係があっても期待どおりに動作します。次の関係があるため、あなたのケースでは正しく機能していないと思います。

  • 参加者の投稿数が多い
  • 参加者のコメントが多い
  • 参加者は投稿に属します
  • 参加者はコメントに属します

参加者が投稿に属しているのはなぜですか? 参加者がコメントに属しているのはなぜですか?

それらの関係を取り除くと、contains は期待どおりに機能しますか?

これらすべての関係が必要であり、HABTM関係を正しく設定している場合。HABTM 関係で ContainableBehaviour を使用する方法を説明しているこの投稿を確認してください。

于 2011-11-15T12:12:10.410 に答える
0

理論的には、それはうまくいくはずです。設定したことを確認してください

var $actsAs = array('Containable');

参照しているすべてのモデルで。

編集:もっとよく見ると、おそらくそうではありません。次のことを試してください...

$this->set(
  "posts", 
  $this->Post->find(
    "all", array(
      "conditions" => array("Post.wall_id" => $wall["Wall"]["id"]), 
      "contain" => array("Participant" => array("User"))
    )
  )
);
于 2011-11-15T11:30:39.690 に答える