エス技研

WordPress、CakePHP、PHP、baserCMSなどの Web系システムを中心に情報を提供します!


CakePHP3でassociatedを使って関連データをまとめて保存する方法(hasOne、hasMany、belongsTo)

      2017/10/28

CakePHP3でassociatedを使って関連データをまとめて保存

 

関連データの想定イメージ

 
 EntryDatas ─┬─ JobDatas1
        ├─ JobDatas2
        └─ JobDatas3
 
求人情報サイトで、1回のエントリー(EntryDatas)で複数の求人(JobDatas)に応募するようなことを想定していまして、1つのエントリーに関連付けて、複数の求人情報もまとめて保存する方法を解説します。
 
 

想定のテーブルイメージ

 
テーブル名は「entry_datas」「job_datas」で、それぞれ以下のような構造を想定しています。
 

 
このテーブルを基にして、「bake all」で各種ファイルを生成したものをベースにします。
 
 

モデルのテーブルファイルの変更

 
まず、モデルのテーブルファイルを修正します。
対象ファイルは「EntryDatasTable.php」です。
 

 
bakeをしただけでは、「EntryDatasTable.php」ファイルには、テーブルの連携(アソシエーション)の情報が記載されませんので、上記の通り、「hasMany」の記述を追加します。
この際、連携先の「JobDatas」のテーブル名の指定は、「JobDatas」でも「job_datas」のどちらでも動きます。
が、規約に則った記述方法は「JobDatas」であろうと思います。
 
 


 

テンプレートファイルの生成

 
続いて、入力のフォームを生成します。
対象ファイルは、「EntryDatas」側の「add.ctp」です。
 

 
「EntryDatas」側の入力フォームは変更しません。
「JobDatas」側の入力フォームを追加します。その際、「job_datas」のテーブル名を指定して記載します。
また、入力エリアを複数設ける場合は「0」「1」...と連番を振っていきます。
 
この際、テーブル名を追記するのは、「JobDatas」側だけです。
 
テーブル名を明記するため、「EntryDatas」側にも書いた方がいいような気もするのですが、「entry_datas.title」のように記述してしまうと、正しく保存されなくなります。
(記述してしまうと、save()関数を実行しても、エラーログは出力されず、falseの処理となるため、原因がよく分からず悩むことになります。)
 
 

コントローラーの変更

 
コントローラーの更新を行います。
対象ファイルは「EntryDatasController.php」です。
 

 
変更箇所は、3行目の一番後ろに「, ['associated' => ['JobDatas']]」を追加するところです。
 
この記述の「JobDatas」の部分は、テーブルファイルに追記した「hasMany」で記述したテーブル名を指定します。
「JobDatas」なのか「job_datas」なのか、テーブルファイルと同じものを指定します。同じではない場合はエラーとなります。
 
 

CakePHP2の情報で CakePHP3でもそうなのか未確認の情報

 
下記の CakePHP2のマニュアルには、いくつか興味深い内容が記述されています。
 

CakePHP は1度に複数のモデルの バリデーションとデータ保存をしてくれる saveAssociated() という 便利なメソッドを提供しています。 また、 saveAssociated() はデータベースの整合性を確保するために トランザクションの機能もサポートしています。 (つまり、あるモデルがデータ保存に失敗した場合は、他のモデルのデータも保存されません)

https://book.cakephp.org/2.0/ja/models/saving-your-data.html#hasone-hasmany-belongsto より抜粋
 
つまりは、この「saveAssociated()」の処理を利用して保存することで、保存時に不具合が発生しても、一部のレコードだけが保存されて整合性が無くなるということはない、ということです。
 
おそらく、CakePHP3にもこの機能があるのだと思いますが、CakePHP3のマニュアルにはそのような明記がなく、具体的な検証は行っていません。
どなたかわかりますでしょうか?
 
また、このようなトランザクション処理を正常に処理するため、MySQLの場合は、データベースのエンジンは「InnoDB」の必要があるようです。
「MyISAM」はトランザクション処理をサポートしていないためです。
 
もし、データの保存がうまくいかない場合は、データベースのエンジンが「MyISAM」でないかを確認することも必要かもしれません。
 
 

CakePHP3の関連記事

CakePHP4のCSS、JavaScript、画像のブラウザへのキャッシュをコントロールする
CakePHP3でレコードを保存(追加、更新、Insert、Update)する複数の方法を紹介
CakePHP3でモデルなしフォームからCSVをアップロードしレコードを更新する方法解説
CakePHP3でPHP Simple HTML DOM Parserを使ってスクレイピングする方法
CakePHP3のInsert On Duplicate Key Update(upsert)構文を解説・バルク処理も
CakePHP3の1対多での連携を中間テーブルを使った多対多の連携に変更するときの手順
CakePHP3でデフォルトのソート条件を設定してユーザの選択肢たソート条件を有効にする方法
CakePHP3で Ajaxを使う方法の解説。3.6以降対応。Successとthenの両方を解説。
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
CakePHP3にOGPをfetch、asignを利用してテンプレートごとに指定する方法を解説
 
その他の「CakePHP3」に関する記事一覧
 
 

 - CakePHP 3.x 4.x 5.x

GoogleAdwords

GoogleAdwords

最後までお読みいただきましてありがとうございます。
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!

Message

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

下記の空欄を埋めてください。 * Time limit is exhausted. Please reload CAPTCHA.

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

※入力いただいたコメントは管理者の承認後に掲載されます。

  関連記事

CakePHP3のUpload Plugin 3.0をバリデーションなど実運用向けのカスタマイズ方法解説・その2
CakePHP3のUpload Plugin 3.0をバリデーションなど実運用向けのカスタマイズ方法解説・その2

CakePHP3でファイル、画像をアップロードするプラグイン、upload plugin 3を導入する手順を解説した記事。3部作のその2でバリデーションなどの実用的なカスタマイズ方法を解説。

MySQL+CakePHPのdate型、datetime型項目は「2999-12-31」までしか扱えない
MySQL+CakePHPのdate型、datetime型項目は「2999-12-31」までしか扱えない

CakePHPの日付、日時の型であるdate型、datetime型の最大値は2999-12-31となっている。MySQLは9999年までなので違いがあるので注意が必要だ。

CakePHP 2.3 Search Pluginで検索処理 その2表示件数を動的に変える方法

CakePHPの検索プラグイン Search Pluginの検索処理の中で動的に表示件数を変える方法です。

CakePHP3にWYSIWYGエディタのCKEditor4を設置、カスタマイズ方法を解説
CakePHP3にWYSIWYGエディタのCKEditor4を設置、カスタマイズ方法を解説

WYSIWYGエディタであるCKEditor4をCDNを利用して簡単にCakePHP3に導入する方法とカスタマイズする方法を解説。CakePHP3にはページごとの振り分けを行うブロック化を利用する。

CakePHP4のフラッシュメッセージの表示場所、デザインを変更する方法を解説
CakePHP4のフラッシュメッセージの表示場所、デザインを変更する方法を解説

CakePHP4のエラーメッセージ、完了メッセージなどを表示するフラッシュ処理の解説。Controller、レイアウトファイル、テンプレートファイルでそれぞれ処理を指定する。

CakePHP3のCakeDC/Usersのログイン後のリダイレクトを設定解説
CakePHP3のCakeDC/Usersのログイン後のリダイレクトとユーザ権限管理の設定解説

CakeDC謹製Usersプラグインの紹介。ログイン認証後にリダイレクトする先の設定方法についての解説と実運用するために必要なコツを解説。便利な仕組みも仕様の理解があって初めてうまく使いこなせる。

CakePHP3のタイムゾーンを協定世界時UTCから日本標準時間JSTにずれを変更する方法
CakePHP3のタイムゾーンを協定世界時UTCから日本標準時間JSTにずれを変更する方法

CakePHP3の標準設定のタイムゾーンは「UTC(協定世界時)」に設定されている。これを日本標準時に変更する方法(app.php、bootstrap.phpの変更方法)の解説。

CakePHP4 のコマンドプログラムからコンポーネントを読み込む方法解説
CakePHP4 のコマンドプログラムからコンポーネントを読み込む方法解説

CakePHP4でコマンドプログラムからコンポーネントを呼び出す方法を解説。コントローラーから呼び出すときと大差はないが、use句でコンポーネントを指定する事がポイント。

CakePHP 2.3 Search Pluginで検索処理 その6ORDER、sortソートの機能

CakePHPの検索プラグイン Search Pluginの検索処理の中で order、ソートについての解説です。

CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説
CakePHP3でパンくずの指定は HTMLヘルパーを使って指定する方法を解説

CakePHP3でパンくずの指定方法の解説。2つのヘルパーがあるが簡単なHTMLヘルパーを使った方法を、実際の状況に合わせて3つのパターン(エレメント化、ブロック化)にして解説。