&pgid();
 
 #contents
 
 ** MT::ObjectとMT::Objectを継承する利点 [#tae86890]
 
 MTではストレージ(DBMファイルやDB)にシリアライズ/保存するすべてのオブジェクトは全てMT::Objectをベースクラスとして表現されています。
 たとえば、エントリーを表すMT::EntryはMT::Objectを継承していて、DBを利用している場合であればmt_entryテーブルに紐付けられています。これによって、mt_entryにある各カラムの値はMT::Entryを使って次のようにアクセスできます。
 
  # entry_id=1のエントリーを取得
  my $entry = MT::Entry->load({id => 1});
  # タイトルを取得(DB利用時であればmt_entry.titleの値が取得される)
  $title = $entry->title; 
  # タイトル変更
  $entry->title('新しいタイトル'); 
  # 変更を保存
  $entry->save or die $entry->errstr;
 
 このようにMT::Objectを継承したクラス群はMTにおいてMVCモデルにおけるモデルクラス(モデルオブジェクト)の役割を果たしています。また、MT::Objectはユーザ(ここでは開発者)に対して次の利点をもたらします。
 - ストレージを意識しないで済む、またDB利用時であってもSQLを書く必要がない
 - MT::Objectによる(上の例のloadメソッドやsaveメソッドなどの)共通したインタフェースで各モデルを操作できる
 - モデルのプロパティを簡単に取得/変更できる
 
 そして、ユーザはMT::Objectを継承した新しいモデルを作成することもできます。
 しかも、この方法を使うことでユーザはDBを使っている場合でも、DBを直接操作することなく、テーブル、カラムの追加、変更を行うことができ、DBのアップグレードも自動で行うような仕組みを利用できます。
 
 ** モデルオブジェクトの作成 [#s6925f51]
 
 例として、商品というモデルの作成を考えてみます。MTベースのECシステムなどを考える場合に作成されそうですね^^
 
 以下の設定で作成します。
 
 |モデル名|Product|
 |クラス|MT::Product|
 |ファイルパス(MTのインストールディレクトリからの相対パス|plugins/Product/lib/MT/Product.pm|
 
 ファイルパスをpluginsの配下にしていますが、これはPluginとして作成することで、
 - インストール/アンインストールを容易にする
 (plugins/Productディレクトリごと消せばそれでアンインストールできる)
 - DBの自動アップグレードを利用できる
 というメリットがあるためにそのようにしています。
 
 参考:[[MovableType拡張プラグラミングに関する10の良い習慣。>http://junnama.alfasado.net/online/2007/07/_movablety.html]]
 
 ※ plugins/Productのディレクトリ名はたまたまモデル名と一致させていますが、他の名前でも問題ありません。このディレクトリ名はプラグイン名に一致するので、例えばプラグイン名をShopにするのであれば、Productモデルはplugins/Shop/lib/MT/Product.pmに作成すればOKです。
 
 Productのデータ構造はIDと商品名、商品説明、販売可能日、価格といったシンプルな形にしてみます。
 
 |プロパティ|型|属性名(意味)|h
 |id|integer not null|ID|
 |name|string(255) not null|商品名|
 |description|text not null|商品説明|
 |available_at|datetime|販売可能日|
 |price|integer not null|価格|
 
 型には論理値を示すbooleanやtimestamp、smallint、bigint、float、blob等が使えます。
 
 ※ lib/MT/ObjectDriver/DDL.pmのdb2type()を見て調べているので、あやまりがあるかもしれません。ドキュメメントが見つからず・・・
 
 以上から、MT::Productsクラス(plugins/Product/lib/MT/Product.pm)は次のようになります。
 
   1:  package MT::Product;
   2:
   3:  use strict;
   4:
   5:  use MT::Object;
   6:  @MT::Product::ISA = qw(MT::Object);
   7:
   8:  __PACKAGE__->install_properties({
   9:          column_defs => {
  10:                  'id' => 'integer not null',
  11:                  'name' => 'string(255) not null',
  12:                  'description' => 'text not null',
  13:                  'available_at' => 'datetime',
  14:                  'price' => 'integer not null',
  15:          },
  16:          indexes => {
  17:                  'id' => 1,
  18:                  'available_at' => 1,
  19:          },
  20:          audit => 1,
  21:          datasource => 'product',
  22:          primary_key => 'id'
  23:  });
  24:
  25:  1;
 
 install_propertiesメソッドのkey = column_defsにデータ構造をプロパティ => 型のハッシュでセットします。
 
 indexesはindexをはるプロパティを指定します。indexに対応しているDBであればインデックスが作成されます。
 
 
 
 
 ** プラグインの作成と自動アップグレード [#l64b2b96]
 
 プラグインを作成します。
 作成したモデルを利用するプラグインを作成します。
 
 ファイル名は何でもよい
 クラス名、ファイル名は何でもよいですが、以下の設定にしておきます。
 
 |クラス名|MT::Plugin::Product|
 |プラグイン|plugins/product.pl|
 
 プラグインでは
 
  use vars qw( $VERSION $SCHEMA_VERSION );
  $SCHEMA_VERSION = '0.2';
 
 のように$SCHEMA_VERSIONを定義し、プラグインオブジェクトのnewで
 
  my $plugin = new MT::Plugin::Product({
      name => '<MT_TRANS phrase=\'InquiryForm Plugin\'>',
       :
      schema_version => $SCHEMA_VERSION,
       :
      object_classes => [
          'MT::Product',
      ],
  });
 
 のようにschema_versionとobject_classesプロパティを指定します。
 
 object_classesには利用するモデルクラス名を配列の参照で指定します。複数のモデルクラスの指定も可能です。そして、schema_versionにはこのプラグインのDBスキーマ(≒利用するモデルクラス)のバージョンを表現します。
 
 後は、通常のプラグインと作り方は何も変わりません。プラグインを作成した後、mt.cgiにブラウザからアクセスすると、DBアップグレードを促す画面が表示され、そのままアップグレードが可能になります。
 
 また、開発を進めていく中で、product.plが利用しているモデルクラスのスキーマが変化したとします。その時は、product.plの$SCHEMA_VERSIONをあげてやれば、再度mt.cgiにアクセスした時に再びDBアップグレードを促す画面が表示されます。$SCHEMA_VERSIONに与えるバージョン番号の採番ルールは自分で決めてよいようです。少なくとも数値として上がっていった場合にはバージョンアップとみなして、アップグレードが走ります。
 
 #blikifooter(進地);

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

アークウェブのサービスやソリューションはこちら