Yiiでリンクモデルを保存する

少し前に、関連レコードの保存(CActiveRecord)を実装するコンポーネントを作成し、このコードを共有したいと思います。



たとえば、クライアントに関するデータをすべての連絡先とともに保存する必要がある場合、頻繁に繰り返されるコードが書かれていることに気付きました。

if ($client->save()) { foreach ($contacts as $contact) { $contact->clientId = $client->primaryKey; $contact->save(); } }
      
      





もちろん、このコードには検証とエラー処理が付随し、トランザクションで終了することもできます。 私がやりたいのは、異なる相互接続モデルを保存するための汎用コードを作成することです。



たとえば、このようなデータをフォームから保存する必要があります。1つの住所と多くの連絡先を持つ新しい顧客。 同時に、クライアントは作成された注文と請求書に関連付けられます。 また、注文は請求書に関連付けられます。 その結果、これらのすべてのモデルは次のように保存できます。

  public function actionCreate() { $order = new Order; $address = new Address; $user = new User; $contacts = array(new Contact); $invoice = new Invoice; if (isset($_POST['Submit'])) { $user->saveWith($address, $_POST['Address'], 'addressId'); $user->saveWith($contacts, $_POST['Contact'], 'userId'); $order->saveWith($user, $_POST['User'], 'userId'); $invoice->saveWith($order, $_POST['Order'], 'orderId'); $invoice->saveWith($user, $_POST['User'], 'userId'); $invoice->attributes = $_POST['Invoice']; if ($invoice->relationalSave()) { echo 'Saved'; } else { echo 'Not saved'; } } $this->render('create', array('order' => $order, 'user' => $user, 'invoice' => $invoice, 'address' => $address, 'contacts' => $contacts)); }
      
      







ご覧のとおり、主なモデルはアカウントであり、クライアント(ユーザー)と注文が保存されています。 注文とともにクライアントも保存され、クライアントとともに連絡先リストと住所も保存されます。



この保存は、1つのモデルをメインモデルと一緒に保存するときに、関連付けられたモデルの主キー値をメインモデルフィールドに保存する必要があるため、この場合の3番目のパラメーターはメインモデルの外部キーの名前になります。 関連するモデルの配列を保存する場合、3番目のパラメーターは関連するモデルの外部キーの名前であると見なします。



2番目のパラメーターは、1つのモデルのデータまたはデータの配列です。このデータは、質量属性の割り当てを使用してモデルに書き込まれます。

 $model->attributes = $_POST['Model'];
      
      





2番目のパラメーターの唯一の制限は、モデル配列がデータ配列に対応する必要があることです。つまり、配列のインデックスは0から始まり、ギャップがない必要があります。 おそらく、この制限を回避できると考えることで。 たとえば、モデルの主キーが入力データにあるかどうかを確認し、データベースからロードできます。この場合、モデルをプリロードして通信を監視する必要はありません。



オプションの4番目のパラメーターもあり、関連するモデルの配列全体を検証します。 たとえば、アカウントに関連付けられている支払い額がアカウントの額と等しいことを確認する必要があります。 これを行うには、検証($モデル)メソッドを含む検証クラスを作成します。このメソッドはモデルのリストを受け入れ、検証が成功または失敗した場合にtrueまたはfalseを返します。 このメソッドは、関連するモデルの配列でそれらを保存する前に呼び出されます。



Yii拡張で CActiveRecordBehaviorとして実装されているコンポーネントを見ることができます



コメント内の問題に対するあなたの意見やその他の解決策は興味深いものになります。



All Articles