LoginSignup
3
3

More than 5 years have passed since last update.

CakePHP に findOrCreate() を実装する

Last updated at Posted at 2014-07-09

概要

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 );
}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3