LoginSignup
65
62

More than 5 years have passed since last update.

FuelPHPのORM Observerはとても便利

Last updated at Posted at 2014-05-28

ORM Observer

FuelPHPのORMパッケージに含まれるオブザーバがとても便利。

イベントベースになっていて、特定のイベント発生時に処理を行うことが出来る。
たとえば、before_insert, before_save, after_loadなどのタイミング。

標準でいくつかのオブザーバが付属していて、自前で作ることもできる。

付属オブザーバ

  • Observer_Self
    • 任意のイベント発生時に、モデルに含まれる任意の関数を実行する
  • Observer_CreatedAt
    • レコードが挿入されたときにcreated_atを設定
  • Observer_UpdatedAt
    • レコードが更新されたときにupdated_atを設定
  • Observer_Validation
    • レコードの挿入・更新前にカラムのデータをバリデーションする
  • Observer_Typing
    • カラムのデータをキャストする
  • Observer_Slug
    • URLのスラグを生成する

試してみる

テストデータ

とりあえず説明用にMySQLに適当なテーブルを追加してテストデータを投入。

CREATE TABLE `students` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '',
  `blood_type` varchar(10) DEFAULT '',
  `favorite_things` text NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ScreenShot 2014-05-28 20.04.54.png

Model_Studentを作成

このような感じで、カラム名や論理削除フラグ、主要な4つのオブザーバを設定。

student.php
class Model_Student extends Orm\Model_Soft
{
    protected static $_primary_key = array('id');

    protected static $_soft_delete = array(
        'mysql_timestamp' => true,
    );

    protected static $_properties = array(
        'id',
        'blood_type' => array(
            'data_type' => 'var_char',
            'validation' => array(
                'match_pattern' => array('@\A(A|B|O|AB)\z@'),
            ),
        ),
        'name' => array(
            'data_type' => 'varchar',
        ),
        'favorite_things' => array(
            'data_type' => 'json',
        ),
        'created_at' => array(
            'data_type' => 'time_mysql',
        ),
        'updated_at' => array(
            'data_type' => 'time_mysql',
        ),
        'deleted_at' => array(
            'data_type' => 'time_mysql',
        )
    );

    protected static $_observers = array(
        'Orm\Observer_Typing' => array(
            'events' => array('before_save', 'after_save', 'after_load')
        ),
        'Orm\Observer_Validation' => array(
            'events' => array('before_insert', 'before_save'),
        ),
        'Orm\Observer_UpdatedAt' => array(
            'events' => array('before_save'),
            'mysql_timestamp' => true,
        ),
        'Orm\Observer_CreatedAt' => array(
            'events' => array('before_insert'),
            'mysql_timestamp' => true,
        ),
    );
}

TypingでJSONもデコード

モデルをfindして取得するだけで、以下のようにキャストされる。

$student = \Model_Student::find(1);

/*
  array (
    'blood_type' => 'O',
    'name' => 'Ichigo Hoshimiya',
    'favorite_things' => 
    stdClass::__set_state(array(
       'color' => 'pink',
       'genre' => 'cute',
       'brand' => 'Angely Sugar',
    )),
    'created_at' => 
    Fuel\Core\Date::__set_state(array(
       'timestamp' => 1349659654,
       'timezone' => 'Asia/Tokyo',
    )),
    'updated_at' => 
    Fuel\Core\Date::__set_state(array(
       'timestamp' => 1401273534,
       'timezone' => 'Asia/Tokyo',
    )),
    'deleted_at' => NULL,
    'id' => '1',
  )
*/

ここにはないけど、int型やfloat型も、もちろんキャストされる。
tinyint(1)のカラムに、data_typeでboolを設定しておくとtrue/falseになったり。とっても便利。

Validationでバリデーション

$student = \Model_Student::find(1);

try
{
    $student->blood_type = 'AC';
    $student->save();
}
catch (\Orm\ValidationFailed $e)
{
    echo $e->getMessage();
    // The field blood_type must match the pattern @\A(A|B|O|AB)\z@.
}

blood_typeに「AC」を入れてsaveしようとしても、match_patternで「A, B, O, AB」のどれかに制限されているのでエラーになる。

CreatedAt, UpdatedAt

もちろんupdateしてsaveすれば、updated_atが更新される。

$student = \Model_Student::find(1);
$student->favorite_things->lucky_charm = 'おしゃもじ';
$student->save();

ScreenShot 2014-05-28 20.15.35.png

Typingマジ便利

JSONの他にもserializeとかも使えるので、こういうケースだと使い勝手がすごくいい。
細かい部分でスキーマレスなデータを取り扱いたくなるとき、ラララ〜って感じで小さく書ける。

65
62
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
65
62