ele_eel's diary

プログラムの事を少しと、デジタル系買物記。

Kohanaライブラリ ORM の Model の設定

公式リファレンスにある例 に沿ってやっていきます。

  • データベース: MySQL 5.1.x
  • Kohana:ver 2.3.4

ORM を利用する際の Model の設定について

リファレンスの例では、テーブルの形式が InnoDB となっています。これは、ORM のリレーショナルシップをテーブルの外部キー( foreign key )で設定する為です。MySQL でもう一つのメジャーな形式 MyISAM では外部キーを設定することができません。どちらの形式を選択するのが良いのかについてはともかく、外部キーを設定できないケースということで MyISAM でやっていきます。

-- ユーザテーブル (MySQL)
CREATE TABLE users (
      id smallint(5) UNSIGNED NOT NULL,
      role_id tinyint(3) UNSIGNED NOT NULL,
      name varchar(20) NOT NULL,
      PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
-- ブログ投稿記事テーブル (MySQL)
CREATE TABLE blog_posts (
      id smallint(5) UNSIGNED NOT NULL,
      user_id int(8) UNSIGNED NOT NULL,
      category_id int(8) UNSIGNED NOT NULL,
      name varchar(20) NOT NULL,
      title varchar(100) NOT NULL,
      contents text NOT NULL,
      PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
 
-- 投稿記事のカテゴリーテーブル (MySQL)
CREATE TABLE categories (
      category_id smallint(5) UNSIGNED NOT NULL,
      name varchar(20) NOT NULL,
      PRIMARY KEY  (id),
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

テーブルを作成したら、さっそく ORM でモデルを作成します。
MyISAM では外部キーをテーブルにて設定できないので、モデル内で指定します。

//Users_Model
class User_Model extends ORM
{
      protected $has_many = array('blog_posts');
}
 
//Blog_Post_Model
class Blog_Post_Model extends ORM
{
      protected $has_one = array('user');
      protected $has_and_belongs_to_many = array('categories');
      //外部キーの設定プロパティ
      protected $foreign_key = array(
            'user' => 'user_id',
      );
}
 
//Category_Model
class Category_Model extends ORM
{
      protected $has_and_belongs_to_many = array('blog_posts');
}

ORM の設定としては以上です。
外部キーをプロパティで array(’モデル名’, ‘外部キーとなるカラム名’) として設定します。テーブルでのプライマリーキーのカラム名が id でない場合、プロパティにて変更できます。その他、プロパティで設定できる主な項目は以下。

// PRIMARY KEY のカラム名が id でない場合の設定
protected $primary_key = 'category_id';
//デフォルトのソート
protected $sorting = array(
        'last_login' => 'desc',
        'username' => 'asc'
  );
//自動で取得するモデル
//with メソッドと同じ
protected $load_with = array('categories');
//データベースのグループ
protected $db = 'test_db';

many_to_many の場合は、その関連データを保存するテーブル(ピボットテーブル)が必要です。テーブル名はモデル名をアルファベット順にアンダーバーでつなげたものになります。例えば、上記の例で言うと blog_posts_categories ですね。カラムは各テーブルのプライマリーキーのみとなります。

-- many_to_many テーブル (MySQL)
CREATE TABLE blog_posts_categories (
      blog_post_id smallint(5) UNSIGNED NOT NULL,
      category_id smallint(5) UNSIGNED NOT NULL,
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

Blog_Post の ID:1を呼び出し、その複数カテゴリーにアクセスするには

//ORM::factory('モデル名', プライマリーキー);
$post = ORM::factory('blog_post', 1);
 
foreach ($post->categories as $category)
{
    echo $category->name;
}

簡単ですね。
とりあえずここまで。