Orm

ORMはオブジェクト 関係マッピングの略です。 これは、2つのことを行います: オブジェクトにデータベースのテーブルの行をマップし、 それはあなたがそれらのオブジェクト間の関係を確立することができます。
それは Active Record パターンに従いますが、 他のシステムに影響も受けます。

Observers: Included observers

付属のオブザーバーは以下に記載されています:

Observer_Self

良い習慣ではありませんが、場合によっては、あなたのモデルとイベントメソッドだけを持っているのはおそらく最も クリーンです。 もしモデルがイベントにちなんで命名され、_event_ で始まるメソッドを持っている場合は、 Observer_Self の出番です。たとえば after_save イベントの場合、 あなたは public メソッドの _event_after_save() を 使っているモデルに追加する必要があり、それは モデル自体のオブザーバの呼び出しを持つことができます。

// オブザーバを追加します
protected static $_observers = array('Orm\\Observer_Self');

// But if you only observe some events you can optimize by only adding those
protected static $_observers = array('Orm\\Observer_Self' => array(
	'events' => array('after_save', 'before_insert')
));

Observer_CreatedAt

このオブザーバはbefore_insertだけに作用します。created_atプロパティを持っている モデルが初めて保存するとき、Unixタイムスタンプがセットされます。

// オブザーバを追加します。
protected static $_observers = array('Orm\\Observer_CreatedAt');

// 設定追加:
// - before_insertのみで実行する必要
// - mysqlのタイムスタンプを使用(デフォルトではUNIXタイムスタンプを使用しています)
// - "created_at"の代わりに"created"を使用
protected static $_observers = array(
	'Orm\\Observer_CreatedAt' => array(
		'events' => array('before_insert'),
		'mysql_timestamp' => true,
		'property' => 'created',
	),
);

Observer_UpdatedAt

This observer acts only upon before_save or before_update and expects your model to have a updated_at property which will be set to the Unix timestamp when saving (also during the first time).

// Don't use this, it will make it run twice!
protected static $_observers = array('Orm\\Observer_UpdatedAt');

// 設定追加:
// - before_saveのみで実行する必要あり
// - mysqlのタイムスタンプを使用(デフォルトではUNIXタイムスタンプを使用しています)
// - "updated_at"の代わりに、"updated"を使用
protected static $_observers = array(
	'Orm\\Observer_UpdatedAt' => array(
		'events' => array('before_save'),
		'mysql_timestamp' => true,
		'property' => 'updated',
	),
);

When you use before_save, the updatedAt column will be updated on both an insert and an update. When you use before_update, the updatedAt column will be updated only on updates.

Observer_Validation

This observer can act on before_insert and/or before_update, or on before_save. Do not use both before_save and one of the others, that would cause your rules to be called twice. It is used to prevent the model from saving if validation rules fail. It uses the Fieldset class and can also generate the form for you.

主要なキーは編集できませんし、検証にも、フォームにも追加されません。 そしてほとんどの場合自動インクリメントとなります。それを創造の上に置いて、確認を必要とする場合、 あなたは手動でフィールドを加える必要があります。

オブザーバーは、以下のようにロードすることができます:

// Just add the Observer, and define the required event
protected static $_observers = array('Orm\\Observer_Validation' => array(
	'events' => array('before_save')
));

Do not define this observer without event types, as that will cause it to be called twice!

Validation rules should be defined in your model in $_properties. This is demonstrated in Creating Models. After you have added the Validation Observer, the Orm\ValidationFailed exception will be thrown when the model's data fails to validate before save. As such, you must try/catch your calls to the save function of a model.

より広範な機能例/scaffolding を以下に示します:

class Controller_Articles extends Controller
{
	public function action_create()
	{
		$view = View::forge('articles/create');
		if (Input::param() != array())
		{
			try
			{
				$article = Model_Article::forge();
				$article->name = Input::param('name');
				$article->url = Input::param('url');
				$article->save();
				Response::redirect('articles');
			}
			catch (Orm\ValidationFailed $e)
			{
				$view->set('errors', $e->getMessage(), false);
			}
		}
		return Response::forge($view);
	}

	public function action_edit($id = false)
	{
		if ( ! ($article = Model_Article::find($id))
		{
			throw new HttpNotFoundException();
		}

		$view = View::forge('articles/edit');
		if (Input::param() != array())
		{
			try
			{
				$article->name = Input::param('name');
				$article->url = Input::param('url');
				$article->save();
				Response::redirect('articles');
			}
			catch (Orm\ValidationFailed $e)
			{
				$view->set('errors', $e->getMessage(), false);
			}
		}
		return Response::forge($view);
	}

	public function action_delete($id = null)
	{
		if ( ! ($article = Model_Article::find($id))
		{
			throw new HttpNotFoundException();
		}
		else
		{
			$article->delete();
		}
		Response::redirect('articles');
	}

}

By default, the HTML representation is passed as message to the ValidationFailed exception object, ready for display in your view. There are however cases where you would like to have access to the individual error messages, for example because you're in a RESTful API call, and you want to return the messages as JSON:

class Controller_Articles extends Controller_Rest
{
	public function action_create()
	{
		$view = View::forge('articles/create');
		if (Input::param() != array())
		{
			try
			{
				$article = Model_Article::forge();
				$article->name = Input::param('name');
				$article->url = Input::param('url');
				$article->save();
				Response::redirect('articles');
			}
			catch (Orm\ValidationFailed $e)
			{
				$errors = array();
				foreach ($e->get_fieldset()->validation()->error() as $error)
				{
					$errors = array(
						'field' => $error->field,					// the field that caused the error
						'value' => $error->value,					// the value that is in error
						'message' => trim($error->get_message(false, '\t', '\t')),	// the error message
						'rule' => $error->rule,						// the rule that failed
						'params' => $error->params,					// any parameters passed to the rule
					);
				}
				return $errors;
			}
		}

		return Response::forge($view);
	}
}

これは、Fieldset クラスを使用しているので、検証を実行し、 また、モデル用のフォームを作成することができます。次の例では、作成と編集フォームが一般的なビューで定義されています。 しかし、同じように簡単にモデルにそれを定義し、 Fieldset::instance() を使用することで、 viewでそれのインスタンスを取得することができます。

// フォームを作成する Model_Article のインスタンスを使用して、あなたはまた、クラス名を渡すことができます。
$fieldset = Fieldset::forge()->add_model($article);

// モデルのインスタンスからの値を使用してフォームを移入します。
// trueを渡しても、セーブ失敗した後に再設定するために POST/PUT を使用します。
$fieldset->populate($article, true);

// フィールドセットは、文字列へのキャスト時に HTML としてビルドされます。
echo $fieldset;

Observer_Typing

これは 2 つのもののためのものです: 入力のための型強制とDBからの出力のための型キャストです。 つまり、 あなたがタイピングオブザーバを保存しているときにすることは予想される型に入力値をキャストしようとすることで、 それができないは例外をスローします。そして、あなたが DB のデータを取得しているとき、 通常、それはすべての文字列になります(偶数整数および浮動小数点数)が、タイピングオブザーバでそれらはそれらのスカラ型にキャストされます。

タイピングオブザーバーは上記のほかに、シリアル&JSONフィールドのサポートを追加します。どちらも 文字列型のフィールドである必要があります("テキスト"が望ましい)。 しかし保存用に (serialize() もしくは json_encode() を使って) エンコードされたの値を持つことになり、そして DB から取得する際には (unserialize() もしくは json_decode() を使って) デコードをします。

Observer_Typing が検証に代わるものとして意図されていないため、検証としてそれを使用しようと しないでください。どちらもあなたのサイトの訪問者によって読まれることを意図してこのオブザーバによってスローされた例外はありません。 コードをデバッグするのに役立つことを意図しています。

// オブザーバを追加します。
protected static $_observers = array('Orm\\Observer_Typing');

// 特定のイベントだけのためのオブザーバーを追加します。
protected static $_observers = array('Orm\\Observer_Typing' => array(
	'events' => array('before_save', 'after_save', 'after_load')
));

このオブザーバーはあなたがそのモデルにセットした $_properties 静的変数を必要としますが、 もしセットされていない場合は DB::list_columns() (MySQL のみ) による検出を利用します。 もし自分で設定を行いたい場合、以下の設定が利用可能です。

パラメータ Valid input 説明
data_type varchar, int, integer, tinyint, smallint, mediumint, bigint, float, double, decimal[:d], text, tinytext, mediumtext, longtext, enum, set, bool, boolean, serialize, json, time_unix, time_mysql フィールド上で使用されるタイピングオブザーバを持っているために必要なSQLデータ型。
null bool Whether null is allowed as a value, default true
character_maximum_length int 文字列データ型のために許可される最大文字数 (varchar, text)
min int 整数の最小値
max int 整数の最大値
options array セットのための有効な文字列値の配列または列挙データ型
注: 現在のオプション自体はカンマを含めることはできません。

In case of data_type "decimal", you can suffix the type with the number of decimals required. If defined, the value returned is a string, formatted with the defined number of decimal digits, and taking the current defined locale into account.

Observer_Slug

このオブザーバは、モデル固有のURL安全スラグを作成します。 それは "before_insert"時にのみ動作し、 あなたのモデルがタイトル(スラグを作成するため)とスラグ(スラグを保存するため)プロパティを持つことを想定しています。

//オブザーバを追加します。
protected static $_observers = array('Orm\\Observer_Slug');

// 設定
protected static $_observers = array(
	'Orm\\Observer_Slug' => array(
		'events' => array('before_insert'),
		'source' => 'title',   // 上にスラグをベースに使用されるプロパティはプロパティの配列かもしれません。
		'property' => 'slug',  // プロパティが空のときにスラグを設定します。
	),
);
protected static $_observers = array('Orm\\Observer_Slug' => array('before_insert'));

オブザーバは Inflector::friendly_title() を使用して title から slug を作成し、スラグが既に存在する場合は、インデックスを追加します。