概要
Laravel の Eloquent ORM で提供されているメソッド、findOrCreate() を CakePHP に移植する。
使い道
User に hasOne や hasMany で依存するテーブルが存在する(Profile など)場合で、User レコードのデータを元に Profile のレコードを新規作成/更新する場合にレコードの存在の有無を気にせずに取得して更新、といった使い方ができる。
コード
モデル内で実行されることを想定しています。 AppModel のような基底クラスを作成して継承させるか、ビヘイビアで実装するかはお好みで。
/**
* レコードを検索し、該当するレコードが存在しない場合には
* 検索した情報でレコードを新規作成する
*
* @access public
* @param Array $params 検索するカラム名と値の配列
* @return Array 該当した、もしくは新規作成されたレコード
*/
public function findOrCreate( $params = array() ) {
$options = array(
'fields' => array( '*' ),
);
// 検索するカラム名、値を conditions 配列に格納する
if ( false === is_array( $params ) ) {
$params = array( 'deleted' => 0 );
}
if ( false === array_key_exists( 'deleted', $params ) ) {
$params['deleted'] = 0;
}
if ( is_array( $params ) ) {
$options['conditions'] = array();
foreach ( $params as $column_name => $param ) {
$options['conditions'][ $this->name . '.' . $column_name ] = $param;
}
}
$record = $this->find( 'first', $options );
// レコードが存在する場合はレコードを返して終了
if ( is_array( $record ) && 1 <= count( $record ) ) {
return $record;
}
// レコードが存在しない場合はレコードを作成する
$this->create();
if ( array_key_exists( $this->primaryKey, $params ) ) {
unset( $params[ $this->primaryKey ] );
}
$params['created'] = date( 'Y-m-d H:i:s' );
$this->save( $params );
return $this->find( 'first', $options );
}