5

UsersCommentsPagesの3 つのモデルがあります。

ユーザー には多数の コメントがあり、コメントは ページに属し ます。

すべてのモデルがこのcontainable動作を使用し、デフォルトはrecursive -1です。

Pageモデルのフィールドを含む contentリクエストを使用してCommentsfind()クエリを呼び出すと、単一のクエリを使用して結果が正しく返され、自動的にPageテーブルがユーザーに結合されます。

Userモデル ( CommentComment.Pageを含む )から同様のクエリを呼び出すと、結果は Comments をソースとするクエリであり、その後に関連するPageをソースするコメントごとのクエリが続きます。

JOIN の最適化を維持するためにモデルを構成する方法はありますか? 関連モデル ( Comments )での belongsTo 宣言は、ホスト モデル ( Users ) まで続くと想定しました。

アップデート

明確にする必要がありますが、私の質問は、実際のケーススタディの簡略化されたバージョンを使用していました。私が必要とする最小限の解決策には、この初期のモデル hasMany モデルの 属している モデル構造が含まれますが、チェーンの下流にある 1 つ以上の追加の属している モデルでの解決策も探しています (これは、LEFT JOIN を自動的に使用します。これは次のようになります)。実行可能)。

4

5 に答える 5

2

うーん、それは面白い。これは、コアに実装する必要がある一種の最適化です:)

とにかく、クエリを少し異なる方法で作成することで、同じ結果(おそらく異なる形式)を得ることができると思います。

$this->User->Comment->find('all', array(
  'conditions' => array(
    'Comment.user_id' => $userId
  ),
  'contain' => array(
    'User',
    'Page'
  )
));

コメントモデルから検索する場合、両方とも1:1の関係であるため、2つの左結合を使用してデータを結合する必要があります。注:結果の配列は、ユーザーモデルから検索した場合とは少し異なる場合があります。

于 2012-10-24T14:42:35.737 に答える
1

では、すべてのクエリを含めるためのより簡単な方法があるかどうかを尋ねていますか?現在のコントローラー内にすべてを含める場合。beforeFilter()コールバックでcontainを実行すると、そのコントローラー内のすべてのクエリに適用されます。

于 2012-10-24T12:43:11.240 に答える
1

以下のようなモデル定義の場合:

  1. コメント モデルは Page と User に属します。
  2. ページはユーザーに属し、多くのコメントがあります。
  3. ユーザーは多くのページとコメントを持っています

次のコードは、結合されたクエリを 1 つ返します。

$this->loadModel('Comment');
$this->Comment->Behaviors->attach('Containable');
$queryResult = $this->Comment->find('all', array(
   'contain' => array(
       'User', 
       'Page'
    )
));

以下のコードは、2 つのクエリを返します。ページとユーザーが 1 つのクエリに結合され、すべてのコメントが別のクエリに結合されました

$this->loadModel('Page');
$this->Page->Behaviors->attach('Containable');
$queryResult = $this->Page->find('all', array(
   'contain' => array(
        'User', 
    'Comment'
   )
));

また、次のコードは、モデルごとに 1 つずつ、3 つのクエリを返します。

$this->loadModel('User');
$this->User->Behaviors->attach('Containable');
$queryResult = $this->User->find('all', array(
    'contain' => array(
        'Page', 
        'Comment'
    )
));
于 2012-11-03T03:32:33.480 に答える
1

あなたの質問を理解しているかどうかはよくわかりませんが、コメント -> ページ リンケージの多くの sql-call に問題があると思いますか? それが正しければ、

  1. SQL呼び出しを減らし、containとほぼ同じように機能するリンク可能な動作を試してください
  2. または、必要なデータがほとんど同じ場合は、特定のモデルで関数を作成し、SQL 呼び出しに満足している場所 (Comment-Model など) でユーザー モデルから呼び出します。$this->Comment->myFindFct($params);

それが役立つことを願っています

編集:私の頭に浮かぶことの1つ。関連付け配列の結合タイプを に変更することができましたinner。これにより、ケーキも関連付けられたモデルの単一呼び出しになりました。

于 2012-10-24T12:58:36.103 に答える
1

これを行う良い方法は、カスタムの find メソッドを作成することです。

たとえば、 User モデル内に呼び出されるメソッドを作成します_findUserComments()。次に、このメソッド内ですべての結合、包含などを行います。次に、コントローラーで、ユーザーのコメントをすべて取得する必要がある場合は、次のように呼び出します。

$this->User->find('UserComments', array(
    "conditions" => array(
        'User.id' => $userId
    )
));

これが役立つことを願っています。

于 2012-10-31T14:50:34.910 に答える