LionHeart SD BLOG

株式会社ライオンハート システムデザインの技術ブログ

インストールしたPropelを実際に利用してみる(その4:Behaviors編[2])

こんにちは、株式会社ライオンハートの鵜飼です。
少し間を空けてしまいましたが今年も引き続きよろしくお願いいたします。

その1その2その3に引き続き、Propelについてのメモその4です。

前回に引き続き、Behaviorsについてのメモを残していきます。公式ドキュメントはコチラですので、併せて参照ください。

AutoAddPk Behavior

プライマリキーを自動的に付与する設定です。

<table name="book">
  <column name="title" type="varchar" required="true" primaryString="true" />
  <behavior name="auto_add_pk" />
</table>

上記のように記述することで、bookテーブルに自動的にidという名前でAutoincrementなプライマリキーが生成されます。
取得する際は、idをカラムとして追加した場合と同じように取得できます。

<?php
$b = new Book();
$b->setTitle('War And Peace');
$b->save();
echo $b->getId(); // 1

コレだけだとそこまで便利そうではありませんが、databaseタグ内にも記載が可能で、指定したデータベース内のテーブル全てにプライマリキーを追加する、ということができます。

<database name="bookstore" defaultIdMethod="native">
  <behavior name="auto_add_pk" />
  <table name="book">
    <column name="title" type="varchar" required="true" primaryString="true" />
  </table>
</database>

プライマリキーは全て同一名で良い、という設計の場合は便利そうな機能ですね。

設定変更

また、下記のように記述すると、idという名前を変更、Autoincrementを解除、データ型の変更をしたりすることができます。

<database name="bookstore" defaultIdMethod="native">
  <behavior name="auto_add_pk">
    <parameter name="name" value="identifier" />
    <parameter name="autoIncrement" value="false" />
    <parameter name="type" value="bigint" />
  </behavior>
  <table name="book">
    <column name="title" type="varchar" required="true" primaryString="true" />
  </table>
</database>

上記の記述で、指定したデータベース内のテーブル全てに、identifierという名前で、Autoincrementではない、BIGINT型のプライマリキーを持ったカラムが追加されます。

Sluggable Behavior

WordPressのURLスラッグの様な、タイトルから自動的に文字列を生成するような事ができる設定です。

<table name="post">
  <column name="id" required="true" primaryKey="true" autoIncrement="true" type="integer" />
  <column name="title" type="varchar" required="true" primaryString="true" />
  <behavior name="sluggable" />
</table>

primaryStringが設定されているカラムをキーに、slugというカラムが自動的に生成されます。

<?php
$p2 = new Post();
$p2->setTitle('Hello, World!');
$p2->save();
echo $p2->getSlug(); // 'hello-world-1'

しかし、日本語は上手く変換はされないようです。

<?php
$p2 = new Model\Post();
$p2->setTitle('記事タイトル');
$p2->save();
echo $p2->getSlug(); // 'n-a'

設定変更

slugカラム名を変更したり、変換パターンを変更することが可能です。

<table name="post">
  <column name="id" required="true" primaryKey="true" autoIncrement="true" type="integer" />
  <column name="title" type="varchar" required="true" primaryString="true" />
  <column name="url" type="varchar" size="100" />
  <behavior name="sluggable">
    <parameter name="slug_column" value="url" />
    <parameter name="slug_pattern" value="/posts/{Title}" />
    <parameter name="replace_pattern" value="/[^\w\/]+/u" />
    <parameter name="replacement" value="-" />
    <parameter name="separator" value="/" />
    <parameter name="permanent" value="true" />
  </behavior>
</table>

変換処理を上書き

createSlug()createRawSlug()を上書きすることで、変換処理を変更することができます。
ちょっと乱暴な判定ですが、下記のように記述することで、日本語文字列にも対応することが可能です。

<?php
protected function createRawSlug()
{
    $title = $this->__toString();

    // URLエンコード判定
    if(preg_match('/[^a-zA-Z0-9\-_\.%]/', $title)) {
        $slug = urlencode($title);
    } else {
        $slug = $this->cleanupSlugPart($title);
    }

    return $slug;
}

Versionable Behavior

バージョン管理を行うことが出来る設定です。

<table name="book">
  <column name="id" required="true" primaryKey="true" autoIncrement="true" type="integer" />
  <column name="title" type="varchar" required="true" />
  <behavior name="versionable" />
</table>

{テーブル名}_versionというテーブルが生成され、保存する度にそちらのテーブルにもデータが登録されます。
また、バージョンを指定してデータを復帰することも可能です。

<?php
$book = new Book();

// 自動的にバージョン番号は加算していきます
$book->setTitle('War and Peas');
$book->save();
echo $book->getVersion(); // 1
$book->setTitle('War and Peace');
$book->save();
echo $book->getVersion(); // 2

// バージョン復帰
$book->toVersion(1);
echo $book->getTitle(); // 'War and Peas'
// 復帰したバージョンで保存
$book->save();
echo $book->getVersion(); // 3

// 指定したバージョンの差分を取得します
print_r($book->compareVersions(1, 2));
// array(
//   'Title' => array(1 => 'War and Peas', 2 => 'War and Pace'),
// );

// 削除時は過去のバージョンデータも削除されます
$book->delete();

リレーションしたデータのバージョニングもできるみたいなので、便利そうですね。

設定変更

バージョン番号を保存するカラム名を変更することが可能です。

<table name="book">
  <column name="id" required="true" primaryKey="true" autoIncrement="true" type="integer" />
  <column name="title" type="varchar" required="true" />
  <column name="my_version_column" type="bigint" description="Version column" />
  <behavior name="versionable">
    <parameter name="version_column" value="my_version_column" />
  </behavior>
</table>

雑感

追加で調べてみましたが、まだまだ面白そうな設定がありました。
もう少しBehaviorもあるみたいなので、続けて次回も残していこうと思います。