7

状況は次のとおりです。「アクション」と「ユーザー」の2つのモデルがあります。これらのモデルは、それぞれテーブル「アクション」および「ユーザー」を参照します。

アクションテーブルに列が含まれていますuser_id。現時点では、すべてのアクションの概要と、それらが割り当てられているユーザーが必要です。を使用するとき$action->fetchAll()は、ユーザーIDしか持っていないので、できればを呼び出さずに、ユーザーモデルのデータを結合できるようにしたいですfindDependentRowset()

モデルにカスタムメソッドとメソッドを作成することを考えましたが、これはデフォルトの動作を壊してfetchAll()しまいfetchRow()ます。find()

この問題を解決するための最良の方法は何ですか?どんな助けでも大歓迎です。

4

3 に答える 3

14

Zend Framework のテーブル リレーションシップ機能を設計および実装しました。

私の最初のコメントは、findDependentRowset()とにかく使用しないということですfindParentRow()。アクションにユーザーへの外部キー参照がある場合に使用します。

$actionTable = new Action();
$actionRowset = $actionTable->fetchAll();
foreach ($actionRowset as $actionRow) {
  $userRow = $actionRow->findParentRow('User');
}

編集: ループには $actionRow と $userRow オブジェクトがあります。オブジェクト フィールドを変更しsave()てオブジェクトを呼び出すことにより、いずれかのオブジェクトを介して変更をデータベースに書き戻すことができます。

Zend_Db_Table_Select クラス (私がプロジェクトを離れた後に実装されたもの) を使用して、Action と User の間の結合に基づいて Rowset を取得することもできます。

$actionTable = new Action();
$actionQuery = $actionTable->select()
  ->setIntegrityCheck(false) // allows joins
  ->from($actionTable)
  ->join('user', 'user.id = action.user_id');
$joinedRowset = $actionTable->fetchAll($actionQuery);
foreach ($joinedRowset as $joinedRow) {
  print_r($joinedRow->toArray());
}

結合クエリに基づくこのような Rowset は読み取り専用であることに注意してください。save()行オブジェクトにフィールド値を設定して、変更をデータベースにポストバックする呼び出しを行うことはできません。

編集:任意の結合された結果セットを書き込み可能にする方法はありません。上記の結合された結果セットに基づく簡単な例を考えてみましょう。

action_id  action_type  user_id  user_name
   1          Buy          1       Bill
   2          Sell         1       Bill
   3          Buy          2       Aron
   4          Sell         2       Aron

次に、action_id=1 の行について、User オブジェクトから取得したフィールドの 1 つを変更します。

$joinedRow->user_name = 'William';
$joinedRow->save();

質問: action_id=2 の次の行を表示すると、'Bill' と 'William' のどちらが表示されますか? 「William」の場合、行 1 を保存すると、この結果セットの他のすべての行で「Bill」が「William」に自動的に更新されなければならないということですか? それともsave()、SQL クエリを自動的に再実行して、データベースから更新された結果セットを取得するという意味ですか? クエリに時間がかかる場合はどうすればよいですか?

オブジェクト指向の設計も考慮してください。各行は個別のオブジェクトです。1 つのオブジェクトを呼び出すとsave()、別のオブジェクトの値が変更されるという副作用があることは適切ですか (オブジェクトの同じコレクションの一部であっても)。これは、コンテンツ カップリングの一種のように思えます。

上記の例は比較的単純なクエリですが、より複雑なクエリも使用できます。Zend_Db は、書き込み可能な結果と読み取り専用の結果を区別する目的でクエリを分析することはできません。これが、MySQL ビューが更新できない理由でもあります。

于 2008-10-26T01:18:51.507 に答える
2

データベースに結合を行うビューをいつでも作成できます。

CREATE OR REPLACE VIEW VwAction AS
SELECT [columns]
  FROM action
  LEFT JOIN user
    ON user.id = action.user_id

次に、使用するだけです

$vwAction->fetchAll();

MySQL のビューは読み取り専用であることを覚えておいてください (これが MySQL であると仮定します)。

于 2008-10-24T21:08:07.000 に答える
1

ビューSQLテーブルを作成することは、ジョイントを作成するための良い解決策ではありませんか? そしてそれにアクセスするための単純なテーブルクラスの後

ロジックがphpよりもsqlにある方が良いと思います

于 2009-10-27T14:06:16.210 に答える