スポンサードリンク

前回DBからデータをひっぱてきて表示させるまでいきました。
最近、会社での仕事でシステムを作るということになったので
せっかくなのでCakePHPを使ってやってみようと思いました。
・・・自分のサイトつくりにも役に立つし♪
なので、仕事で使う内容なども入れてやっていきます。
どれくらいで作れるのかな?
スポンサードリンク
テーブルの結合の仕方
今回はテーブルを結合して表示させてたいと思ったのですが、
まずどういう風にやるのかわかりませんでした。
SQLならJOINとかWHERE使うんだけど、
CakePHPではどういう風に書くのだろう?
色々調べてみると
CakePHPではアソシエーションと言って
モデルのなかに記述すると結合できるようです。
種類は以下の4つあります
・hasOne
・hasMany
・belongsTo
・hasAndBelongsToMany
イメージだとこんな感じでしょうか?

固有のidを持っているモデルから、そのidが使われているモデルへ向けてはhasOneとhasManyで
逆に他のモデルの固有のidを使っているモデルから、固有のidを持っているモデルへ向けてはbelognsToかな?
hasAndBelongsToManyは【多対多】で間にテーブルを用意しなければいけないみたい。
今回は、試していません。
他の3つを試してみた感じ以下のようです。
hasOne
主になるテーブルidに関連するものが結合されるテーブルにある場合で1つの結果を出す
(例)
※Postモデルで処理する場合
モデル名 | Postモデル | → | UserPostモデル |
---|---|---|---|
テーブル名 | posts | → | user_posts |
関連するフィールド名 | id | → | post_id |
Postモデルには基本こんな感じで書きます。
<?php class Post extends AppModel{ public $hasOne = 'UserPost'; //結合モデル } ?>
上記で命名規則に従っていれば自動的にLEFT JOINされます。
オプションで指定する場合は以下のようです。
<?php class Post extends AppModel{ public $hasOne = 'array( 'UserPost'=>array( 'className' => 'UserPost', 'foreignKey'=> 'post_id', 'conditions'=> array('UserPost.status'=>1), 'fields' => null , 'order'=> null , 'dependent'=> true, ) ); } } ?>
●className: 関連付けられるモデルのクラス名。
●foreignKey: アソシエーション先のモデルを検索するための外部キーの名前。デフォルト値は元モデルの単数形に _id がついたもの。
●conditions: array(‘Profile.approved’ => true) のような、find()に指定するconditionsと互換性のある配列、もしくはSQL文字列を指定します。(WHEREみたいな感じかな?)
●fields: 取得するフィールドのリスト。デフォルトで全フィールドが含まれます。
●order: array(‘Profile.last_name’ => ‘ASC’) のような、find()に指定するorderと互換性のある配列、もしくはSQL文字列を指定します。
●dependent: このキーにtureがセットされていて、かつモデルのdeleteメソッドのcascadeパラメータにtrueがセットされて呼び出された時、アソシエーション先のモデルのレコードも一緒に削除されます。
取り出し方はviewで
<?php echo h($product['モデル名']['カラム名']); ?>
で表示される。
スポンサードリンク
hasMany
上記のhasOneが【1対1】で1つの結果しか返さないのと比べて
hasManyは【1対多】なので複数の結果を返してくれる。
しかし、hasManyはLEFT JOINするわけではなく
SQLを複数出します。
例えば、1つhasManyでアソシエーションすると
2つSQLを発動します。
結果は連想配列にまとめられます。
(例)
※Postモデルで処理する場合
モデル名 | Postモデル | → | UserPostモデル |
---|---|---|---|
テーブル名 | posts | → | user_posts |
関連するフィールド名 | id | → | post_id |
Postモデルには基本こんな感じで書きます。
<?php class Post extends AppModel{ public $hasMany = 'UserPost'; //結合モデル } ?>
上記で命名規則に従っていれば自動的にLEFT JOINされます。
オプションで指定する場合は以下のようです。
<?php class Post extends AppModel{ public $hasMany = 'array( 'UserPost'=>array( 'className' => 'UserPost', 'foreignKey' => 'post_id', 'conditions' => array('UserPost.status' => '1'), 'order' => 'UserPost.created DESC', 'limit' => '5', 'dependent' => true ) ); } } ?>
●className: 関連付けられるモデルのクラス名。
●foreignKey: 外部キーの名前。デフォルト値はアソシエーション先のモデルの単数形に _id がついたものです。
●conditions: array(‘Comment.visible’ => true) のような、find()に指定するconditionsと互換性のある配列、もしくはSQL文字列を指定します。
●order: array(‘Profile.last_name’ => ‘ASC’) のような、find()に指定するorderと互換性のある配列、もしくはSQL文字列を指定します。
●limit: アソシエーションモデルのデータの最大行数。
●offset: アソシエーションモデルのデータをスキップする行数。
●dependent: trueをセットすれば、データを再帰的に削除するようになります。たとえばPostレコードが削除されたら、UserPostレコードも削除されます。
●exclusive: trueをセットすれば、deleteAll()を呼び出した時にデータを再帰的に削除するようになります。
●finderQuery: アソシエーションモデルのレコードを取得する時に使われるSQLクエリ。取得結果をカスタムしたい時に使います。
(例)Apple hasMany Orangeというアソシエーションの場合、以下のようなクエリになるでしょう。SELECT Orange.* from oranges as Orange WHERE Orange.apple_id = {$__cakeID__$};
取り出し方はviewで
<?php echo h($product['モデル名']['カラム名']); ?>
belongsTo
hasOneを逆のモデルから見た場合で
結果はhasOneと同じ結果が返ります。
(例)
※UserPostモデルで処理する場合
モデル名 | Postモデル | ← | UserPostモデル |
---|---|---|---|
テーブル名 | posts | ← | user_posts |
関連するフィールド名 | id | ← | post_id |
UserPostモデルには基本こんな感じで書きます。
<?php class UserPost extends AppModel{ public $blongsTo = 'Post'; //結合モデル } ?>
上記で命名規則に従っていれば自動的にLEFT JOINされます。
オプションで指定する場合は以下のようです。
<?php class UserPost extends AppModel{ public $belongsTo = 'array( 'Post'=>array( 'className' => 'Post', 'foreignKey' => 'post_id' ) ); } } ?>
●className: 関連付けられるモデルのクラス名。
●foreignKey: アソシエーション先のモデルを検索するための外部キーの名前。デフォルト値はアソシエーション先のモデルの単数形に _id がついたものです。
●conditions: array(‘User.active’ => true) のような、find()に指定するconditionsと互換性のある配列、もしくはSQL文字列を指定します。
●type: SQLクエリで使われるテーブル結合種別。結合タイプをleft、right、inner、crossの中から選べる。
●fields: アソシエーション先のモデルから取得するフィールドのリスト。デフォルトで全フィールドが含まれます。
●order: array(‘User.username’ => ‘ASC’) のような、 find()に指定するorderと互換性のある配列、もしくはSQL文字列を指定します。
●counterCache: trueをセットすれば、アソシエーション先のモデルでsave() または delete() を実行した時に、テーブルの”[モデル名の単数形]_count”というフィールドの値を増減します。文字列を指定すれば、指定された文字列のフィールドに対してカウントの操作を行います。キーにフィールド名、値に条件、という配列で指定することもできます。このフィールドの値は関連データの行数を表します。
●counterScope: conterCacheのフィールドを更新する際の追加条件があれば指定します。
取り出し方はviewで
<?php echo h($product['モデル名']['カラム名']); ?>
なかなか覚えられない感じですけど、
使い方次第では簡単にJOINしてくれるので便利ですよね。
今回参考にさせて頂いたサイトです。
cakePHP2.1でJoinする
スポンサードリンク