作成または更新は、モデルの ID 列を通じて制御されます。 $Model->id が設定されている場合、この主キーを持つレコードが更新されます。 それ以外の場合は、新しいレコードが作成されます:
このメソッドは、モデルの状態をリセットして新しい情報を保存します。 実際にはデータベースに新しいレコードは作成されませんが、プリセットされた Model::$id がクリアされ、データベース列のデフォルトに基づいて Model::$data にデフォルト値が設定されます。
$data パラメーターが (上記の配列形式を使用して) 渡された場合、モデル インスタンスはこのデータを保存する準備が整います ($this->data を使用して)。
配列の代わりに false がこのメソッドに渡された場合、モデルは、以前に設定されていないモデル構造に従って実際には列を初期化せず、設定された列のみをリセットし、未設定の列はそのまま残します。 これは、データベースにすでに設定されている列の値が更新されるのを避けるために行われます。
既存の行を更新する代わりに新しい行を挿入したい場合は、最初に create() を呼び出す必要があります。これにより、コールバックまたは他の場所で呼び出された保存との競合が回避されます。
単一列の値を保存するために使用されます。 saveField() を使用する前に、モデル ID ($this->ModelName->id = $id) を設定します。このメソッドを使用する場合、$fieldName にはモデル名や列ではなく、列名のみを含める必要があります。
callbacks コールバックを無効にするには false に設定します。 「before」または「after」を使用すると、指定されたコールバックのみが許可されます。
1 回の呼び出しで 1 つ以上のレコードを更新します。更新されるレコードは $conditions 配列によって識別され、$fields パラメーターで指定された列と値が更新されます。
2 array('Ticket.status' => "'closed'"),
3 配列('Ticket.customer_id' => 453)
4);
デフォルトでは、updateAll() は結合をサポートするデータベースのbelongsTo 関連付けに自動的に接続します。この接続は、関連付けを一時的にバインドすることで防止できます。
Model::saveMany(array $data = null, array $options= array())
このメソッドは、同じモデルの複数の行を同時に保存するために使用されます。次のオプションを指定できます:
validate: 検証を無効にするには false に設定し、保存する前に各レコードを検証するには true に設定し、保存する前にすべてのレコードをチェックするには 'first' (これがデフォルト) に設定します。
アトミック: true (デフォルト) の場合、すべてのレコードが単一の命令で保存されます。データベース/テーブルが単一の命令をサポートしていない場合は、false に設定する必要があります。
fieldList: Model::save() メソッドの $fieldList パラメーターと同じです。
deep: (バージョン 2.1 以降) true に設定すると、関連データも保存されます。saveAssociated を参照してください。
単一モデルの複数のレコードを保存するには、$data は数値インデックス付きのレコード配列である必要があります。
1 $data = 配列(
2 配列('タイトル' => 'タイトル 1'),
3 配列('タイトル' => 'タイトル 2'),
4);
メモ
$data に通常含まれる Article キーの代わりに数値インデックスを渡します。同じモデルの複数のレコードを保存する場合、モデルのキーではなく数値を使用してレコード配列にインデックスを付ける必要があります。
次の形式のデータも受け入れることができます:
1 $data = 配列(
2 array('記事' => 配列('タイトル' => 'タイトル 1')),
3 array('記事' => 配列('タイトル' => 'タイトル 2')),
4);
$options['deep'] = true で関連データも保存したい場合、上記の 2 つの例は次のコードのようになります:
1 $data = 配列(
2 array('title' => 'title 1', 'Assoc' => array('field' => 'value')),
3 配列('タイトル' => 'タイトル 2'),
4);
5 $data = 配列(
6 array('Article' => array('title' => 'title 1'), 'Assoc' => array('field' => 'value')),
7 array('記事' => 配列('タイトル' => 'タイトル 2')),
8);
9 $Model->saveMany($data, array('deep' => true));
新しいレコードを作成する代わりにレコードを更新したい場合は、データ行に主キー インデックスを追加する必要があることに注意してください。
1 $data = 配列(
2 array('Article' => array('title' => '新しい記事')), // 新しいレコードを作成します
3 array('Article' => array('id' => 2, 'title' => 'title 2')), // 既存のレコードを更新します
4);
Model::saveAssociated(array $data = null, array$options = array())
このメソッドは、複数のモデルの関連付けを一度に保存するために使用されます。次のオプションを指定できます:
validate: 検証を無効にするには false に設定し、保存する前に各レコードを検証するには true に設定し、保存する前にすべてのレコードをチェックするには 'first' (これがデフォルト) に設定します。
atomic: true (デフォルト) の場合、すべてのレコードが 1 つの命令で保存されます。データベース/テーブルが 1 つの命令をサポートしていない場合は、false に設定する必要があります。
fieldList: Model::save() メソッドの $fieldList パラメーターと同じです。
deep: (バージョン 2.1 以降) true に設定すると、関連データも保存されます。saveAssociated を参照してください。
レコードを保存すると同時に hasOne またはbelongsTo が関連付けられているレコードも保存するには、データ配列は次のようになります:
1 $data = 配列(
2 'ユーザー' => array('ユーザー名' => 'ビリー'),
3 'プロフィール' => array('性別' => '男性', '職業' => 'プログラマー'),
4);
レコードを保存すると同時に hasMany が関連付けられているレコードも保存するには、データ配列は次のようになります:
1 $data = 配列(
2 '記事' => array('タイトル' => '最初の記事'),
3 'コメント' => array(
4 array('body' => 'コメント 1', 'user_id' => 1),
5 array('body' => 'コメント 2', 'user_id' => 12),
6 array('body' => 'コメント 3', 'user_id' => 40),
7)、
8);
レコードを保存しながら、2 レベル以上の深さの hasMany に関連付けられたレコードも保存するには、データ配列は次のようになります:
1 $data = 配列(
2 'ユーザー' => array('email' => 'john-doe@cakephp.org'),
3 'カート' => array(
4 配列(
5 'payment_status_id' =>
6 'total_cost' => 250,
7 'CartItem' => array(
8 array(
9 'cart_product_id' =>
10 '数量' => 1,
11 'コスト' => 100,
12 )、
13 array(
14 'cart_product_id' =>
15 '数量' => 1,
16 'コスト' => 150,
17 )
18)
19)
20)
21);
メモ
保存が成功すると、メイン モデルの外部キーが関連モデルの id 列に保存されます (例: $this->LargeModel->id)。
警告
アトミック オプションを false に設定して saveAssociated メソッドを呼び出す場合は、論理値ではなく配列が返されるので注意してください。
バージョン 2.1 で変更: 深い関連付けからデータを保存できるようになりました ($options['deep'] = true で設定)。
hasMany の関連付けと深く関連付けられたコメントの所属データを持つ関連レコードも保存しながら、レコードを保存するには、データ配列は次のようになります::
1 $data = 配列(
2 '記事' => array('タイトル' => '私の最初の記事'),
3 'コメント' => array(
4 array('body' => 'コメント 1', 'user_id' => 1),
5 array('body' => '新しいユーザーも保存', 'User' => array('first' => 'mad', 'last' => 'coder')),
6)、
7);
そして次のステートメントを使用して保存します:
1 $Article->saveAssociated($data, array('deep' => true));
バージョン 2.1 で変更: Model::saveAll() およびファミリー メソッドは、複数のモデルの fieldList の受け渡しをサポートするようになりました。
複数のモデルに fieldList を渡す例:
1 $this->SomeModel->saveAll($data, array(
)
2 'fieldList' => array(
3 'SomeModel' => array('field_1'),
4 'AssociatedModel' => array('field_2', 'field_3')
5)
6 ));
fieldList は、モデルのエイリアスをキーとして、列の配列を値として持つ配列です。 モデル名は保存データと同じものが使用され、ネストすることはできません。
Model::saveAll(array $data = null, array $options =array())
saveAll 関数は、savaMany メソッドと saveAssociated メソッドの単なるラッパーです。データを検査し、どのタイプのデータ保存を実行するかを決定します。データを見て、実行する保存の種類を決定します。データが数値インデックス付き配列の場合は saveMany が呼び出され、それ以外の場合は saveAssociated が呼び出されます。
この関数のオプションは前の 2 つの関数と同じであり、下位互換性があります。実際の状況に応じて、saveMany または saveAssociated を使用することをお勧めします。
関連するモデルデータを保存する(hasOne、hasMany、belongsTo)
関連するモデルを操作する場合、モデルデータの保存は常に対応する CakePHP モデルによって行われることに注意してください。新しい投稿とそれに関連付けられたコメントを保存する場合は、保存操作中に投稿モデルとコメント モデルの両方を使用する必要があります。
システムに関連付けられたモデル レコードがない場合 (たとえば、新しいユーザーを保存し、関連するプロファイル レコードを同時に保存する場合)、最初にメイン モデルまたは親モデルを保存する必要があります。
これがどのように機能するかを理解するために、新しいユーザーと関連するプロファイルの保存を処理するコントローラー内のアクションがあると想像してください。次のアクション例では、単一のユーザーと単一のプロファイルを作成するのに十分なデータが (FormHelper を使用して) POST されたことを前提としています。
1 パブリック関数 add() {
2 if (!empty($this->request->data)) {
3 // ユーザーデータを保存できます:
4 // $this->request->data['User'] に配置されます
5
6 $user = $this->User->save($this->request->data);
7
8 // ユーザーが保存されている場合は、この情報をデータに追加してプロファイルを保存します。
9
10 if (!empty($user)) {
11 // 新しく作成されたユーザー ID が $this->User->id に割り当てられました。
12 $this->request->data['Profile']['user_id'] = $this->User->id;
13
14 // ユーザーには 1 つのプロファイルがあるため、プロファイル モデルにはユーザー モデルを通じてアクセスできます。
15 $this->ユーザー->プロフィール->保存($this->リクエスト->データ);
16 }
17 }
18 }
原則として、hasOne、hasMany、belongsTo との関連付けに関しては、すべてキーが問題になります。基本的な考え方は、あるモデルからキーを取得し、それを別のモデルの外部キー列に入れることです。これには、保存されたモデル クラスの $id 属性の使用が必要な場合もありますが、コントローラー アクションに POST するフォームの非表示の入力から取得した ID のみが必要な場合もあります。
上記の基本メソッドの補足として、CakePHP は非常に便利なメソッド saveAssociated() も提供します。これを使用すると、複数のモデルを短時間で確認して保存できます。さらに、saveAssociated() は、データベース内のデータの整合性を確保するためのトランザクション サポートも提供します (たとえば、1 つのモデルが保存に失敗した場合、もう 1 つのモデルは保存されません)。
メモ
MySQL でトランザクションが適切に動作するには、テーブルで InnoDB エンジンを使用する必要があります。 MyISAM テーブルはトランザクションをサポートしていないことに注意してください。
saveAssociated() を使用して Company モデルと Account モデルを同時に保存する方法を見てみましょう。
まず、会社とアカウントの両方のフォームを作成する必要があります (会社には多くのアカウントがあると仮定します):
1 echo $this->Form->create('Company', array('action' => 'add'));
2 echo $this->Form->input('会社名', array('ラベル' => '会社名'));
3 echo $this->Form->input('Company.description');
4 echo $this->Form->input('Company.location');
5
6 echo $this->Form->input('Account.0.name', array('label' => 'アカウント名'));
7 echo $this->Form->input('Account.0.username');
8 echo $this->Form->input('Account.0.email');
9
10 echo $this->Form->end('Add');
アカウントモデルのフォーム列に名前を付ける方法を見てください。 Company がメイン モデルの場合、saveAssociated() は、関連付けられたモデル (Account) データが指定された形式で配列に入れられることを期待します。必要な Account.0.fieldName があります。
メモ
上記の列の名前付けは、hasMany 関連付けに必要です。関連付けが hasOne の場合、関連付けられたモデルには ModelName.fieldName を使用する必要があります。
これで、 CompaniesController で add() アクションを作成できます。
1 パブリック関数 add() {
2 if (!empty($this->request->data)) {
3 // 検証エラーを回避するには、次のメソッドを使用します:
4 unset($this->Company->Account->validate['company_id']);
5 $this->Company->saveAssociated($this->request->data);
6 }
7 }
これですべての手順です。これで、会社モデルとアカウントモデルが同時に検証され、保存されます。デフォルトでは、saveAssociated は渡されたすべての値をチェックし、各保存を実行しようとします。
データ経由で保存できるものがたくさんあります
結合テーブルに存在する2つのモデルのデータがどのように保存されるかを見てみましょう。 「hasMany Through (モデルの結合)」セクションに示すように、結合テーブルは hasMany タイプの関係を使用して各モデルに関連付けられます。 私たちの例には、ケーキ スクールのディレクターから、生徒が特定のクラスに出席した日数と成績を記録できるプログラムを書いてほしいという依頼が含まれていました。サンプルコードは次のとおりです:
1 // コントローラー/CourseMembershipController.php
2 クラス CourseMembershipsController は AppController を拡張します {
3 public $uses = array('CourseMembership');
4
5 パブリック関数 Index() {
6 $this->set('courseMembershipsList', $this->CourseMembership->find('all'));
7 }
8
9 パブリック関数 add() {
10 if ($this->request->is('post')) {
11 if ($this->CourseMembership->saveAssociated($this->request->data)) {
12 $this->redirect(array('action' => 'index'));
13 }
14 }
15 }
16 }
17
18 // 表示/コースメンバーシップ/add.ctp
19
20 Form->create('CourseMembership');
21 Form->input('Student.first_name') ?>
22 Form->input('Student.last_name') ?>
23 Form->input('Course.name') ?>
24 Form->input('CourseMembership.days_attended') ?>
25 Form->input('CourseMembership.grade') ?>
26
保存
27 Form->end() ?>
送信されたデータ配列は次のとおりです:
1 配列
2 (
3 [生徒] => 配列
4 (
5 [名前] => ジョー
6 [姓] =>
7)
8
9 [コース] => 配列
10 (
)
11 [名前] => ケーキ
12)
13
14 [コースメンバーシップ] => 配列
15 (
)
16 [出席日数] => 5
17 [グレード] => A
18)
19
20)
Cake は、このデータ構造で 1 回の saveAssociated 呼び出しを使用して、一度に多数を保存し、Student と Course の外部キーを CouseMembership に割り当てます。CourseMembershipsController でインデックス アクションを実行すると、find('all') から取得されたデータ構造になります。は次のとおりです:
1 配列
2 (
3 [0] => 配列
4 (
5 [コースメンバーシップ] => 配列
6 (
7 [id] => 1
8 [学生ID] => 1
9 [コースID] => 1
10 [出席日数] => 5
11 [成績] =>
12)
13
14 [学生] => 配列
15 (
)
16
17 [名前] => ジョー
18 [姓] =>
19)
20
21 [コース] => 配列
22(
)
23
E24 [名前] = & gt;
25)
26)
27)
もちろん、接続されたモデルを操作する方法はたくさんあります。上記のバージョンでは、すべてをすぐに保存することを前提としています。 Student と Course を個別に作成し、後で CourseMembership との関連付けを指定したい場合もあります。 したがって、リストまたは ID と 2 つの CourseMembership メタ列によって既存の学生とコースを選択できるフォームが考えられます。例:
1 // 表示/CourseMemberships/add.ctp
2
3 Form->create('CourseMembership');
4 Form->input('Student.id', array('type' => 'text', 'label' => '学生 ID', 'default' =>1));
5 Form->input('Course.id', array('type' => 'text', 'label' => 'コース ID', 'default' =>1));
6 Form->input('CourseMembership.days_attended') ?>
7 Form->input('CourseMembership.grade') ?>
8
保存
9 Form->end() ?>
結果の POST データ:
1 配列
2 (
3 [生徒] => 配列
4 (
5 [id] => 1
6)
7
8 [コース] => 配列
9 (
10 [id] => 1
11)
12
13 [コースメンバーシップ] => 配列
14 (
)
15 [出席日数] => 10
16 [グレード] => 5
17)
18)
Cake は saveAssociated を使用して学生 ID とコース ID を CourseMembership にプッシュします。
関連モデルデータの保存(HABTM)
hasOne、belongsTo、および hasMany を使用して関連モデルを保存するのは非常に簡単です。関連モデルの ID を外部キー列に入力するだけです。 入力した後、モデル上で save() メソッドを呼び出すだけで、すべてが正しく接続されます。 以下は、タグ モデルの save() メソッドに渡されるデータ配列の形式の例です:
1 配列
2 (
3 [レシピ] => 配列
4 (
5 [id] => 42
6)
7 [タグ] => 配列
8 (
] 9 [名前] = & gt;
10)
11)
saveAll() でこの形式を使用して、HABTM に関連付けられた複数のレコードとモデルを保存することもできます。形式は次のとおりです。
1 配列
2 (
3 [0] => 配列
4 (
5 [レシピ] => 配列
6 (
7 [id] => 42
8 )
9 [タグ] =>配列
10 (
11 [名前] =>イタリア語
12 )
13 )
14 [1] =>配列
15 (
16 [レシピ] =>配列
17 (
18 [id] => 42
19 )
20 [タグ] =>配列
21 (
22 [名前] =>パスタ
23 )
24 )
25 [2] =>配列
26 (
27 [レシピ] =>配列
28 (
29 [id] => 51
30 )
31 [タグ] =>配列
32 (
33 [名前] =>メキシコ人
34 )
35 )
36 [3] =>配列
37 (
38 [レシピ] =>配列
39 (
40 [id] => 17
41 )
42 [タグ] =>配列
43 (
44 [名前] =>アメリカ人(新規)
45 )
46 )
47)
上の数値グループが saveAll() に渡され、含まれるタグが作成され、それぞれがそれぞれのレシピに関連付けられます。
例として、レシピに関連する新しいタグと実行期間の生成の表を作成しました。
この完璧な表单の如く:(我们假定 $recipe_id 已经設定了):
1 Form->create('Tag'); ?>
2 Form->input(
3 'レシピ.id'、
4 array('type' => 'hidden', 'value' => $recipe_id)
5 ); ?>
6 Form->input('Tag.name'); ?>
7 Form->end('タグの追加'); ?>
この例では、レシピの ID として設定されている、Recipe.id 隠しドメインが表示されます。
コントロール内で save() メソッドを使用して、HABTM データをデータ库に自動的に保存します:
1 パブリック関数 add() {
2 // 保存关联
3 if ($this->タグ->save($this->request->data)) {
4 // 保存成功後の要旨
5 }
6 }
このセグメント コードは新しいタグを作成し、レシピに関連付けます。その ID は $this->request->data['Recipe']['id'] で設定されます。
特定の状況では、提示された関連データにダウンローディング選択リストを含めることができると考えられます。放进 :
1 // 制御器中の代コード:
2 $this->set('tags', $this->レシピ->タグ->find('list'));
1 // 動画中の代コード:
2 $this->Form->input('tags');
より可能性の高いシナリオは、HABTM 関係に複数の選択を許可する が含まれていることです。たとえば、レシピに複数のタグを割り当てることができます。この場合も同様にモデルからデータを取り出しますが、フォーム入力の定義が少し異なります。タグの命名には ModelName 規則が使用されます:
1 // コントローラー内のコード:
2 $this->set('tags', $this->レシピ->タグ->find('list'));
1 // ビュー内のコード:
2 $this->フォーム->input('タグ');
上記のコードを使用すると、複数の選択を含むドロップダウン リスト (選択) が作成され、データベースに追加または保存されたレシピに複数の選択を自動的に保存できるようになります。
HABTM が複雑になった場合はどうすればよいですか?
デフォルトでは、Cake は HABTM 関係を保存するときに、まず結合テーブル内のすべての行を削除します。 たとえば、10 の児童団体からなるクラブがあります。 2人の子供を持つクラブを更新します。クラブの子供は12名ではなく2名のみとなります。
HABTM を使用して結合テーブルにさらに列 (ビルド時間またはメタデータ) を追加したい場合は可能であることに注意してください。簡単なオプションがあることを理解することが重要です。
2 つのモデル間の HasAndBelongsToMany 関連付けは、実際には、hasMany とbelongsTo の両方の関連付けを持つ 3 つのモデルの関係の略称です。
次の例を考えてみましょう:
子供はたくさんのクラブに所属しています
もう 1 つの方法は、メンバーシップ モデルを追加することです:
子供には多くのメンバーシップがあります
会員の所属は子供向け、クラブ
クラブには多くの会員がいます。
これら 2 つの例はほぼ同じです。これらは、データベース内で同じ名前の金額列を使用し、モデル内でも同じ金額を使用します。最も重要な違いは、「結合」テーブルの名前が異なり、その動作がより予測しやすいことです。
ヒント
結合テーブルに外部キー以外の拡張列が含まれている場合、配列の 'unique' を "'keepExisting'" に設定することで、拡張列の値が失われるのを防ぐことができます。同様に、'unique' => true とすることで、保存時に拡張カラムのデータが失われないと考えられます。 HABTM 関連付け配列を参照してください。
ただし、多くの場合、HABTM 関連付けを使用する代わりに、結合テーブルのモデルを構築し、上記の例のように hasMany、belongsTo 関連付けを設定する方が簡単です。
データシート
CakePHP は非データベース駆動型のデータ ソースを持つことができますが、ほとんどの場合はデータベース駆動型です。 CakePHP は、MySQL、MSSQL、Oracle、PostgreSQL、およびその他のデータベースで動作するように設計されています。 通常使用しているデータベース システムにテーブルを作成できます。モデル クラスを作成すると、モデルは確立されたテーブルに自動的にマッピングされます。テーブル名は複数の小文字に変換され、複数単語のテーブル名の単語はアンダースコアで区切られます。たとえば、Ingredient という名前のモデルには、intelligent という名前のテーブルがあります。 EventRegistration という名前のモデルは、event_registrations という名前のテーブルに対応します。 CakePHP はテーブルを調べて各列のデータ型を決定し、この情報を使用してビューに出力されるフォームフィールドなどのさまざまな機能を自動化します。列名は小文字に変換され、アンダースコアで区切られます。
作成および変更された列を使用する
作成および変更された列をデータベーステーブルの datetime 列として定義することにより、CakePHP はこれらのフィールドを識別し、レコードがデータベースに作成された時刻と保存された時刻を自動的に入力できます (保存されたデータにこれらのフィールドが既に含まれている場合を除く) ) 価値)。
レコードが最初に追加されるとき、作成および変更された列は現在の日付と時刻に設定されます。既存のレコードが保存されると、変更された列が現在の日付と時刻に更新されます。
Model::save() の前に $this->data に更新、作成、変更されたデータ (Model::read や Model::set など) が含まれている場合、これらの値は $this->data から取得されます。自動的に取得され、更新されません。 または、unset($this->data['Model']['modified']) などのメソッドを使用します。これを行うために Model::save() メソッドをオーバーライドすることはいつでも可能です:
1 クラス AppModel はモデルを拡張します {
2
3 パブリック関数 save($data = null, $validate = true, $fieldList = array()) {
4 // 各保存操作の前に、変更されたフィールド値をクリアします:
5 $this->set($data);
6 if (isset($this->data[$this->alias]['modified'])) {
7 unset($this->data[$this->alias]['modified']);
8 }
9 returnparent::save($this->data, $validate, $fieldList);
10 }
11
12 }
http://www.bkjia.com/PHPjc/477776.html www.bkjia.com 本当 http://www.bkjia.com/PHPjc/477776.html 技術記事 データの保存 CakePHP は、保存されたモデル データのスナップショットを取得します。保存するデータは、次の基本形式を使用してモデルの save() メソッドに渡されます: 1 Array 2 ( 3 [ModelName] = Array 4 ( 5...
)