process S+D

developing process with symfony and doctrine

作成したスキーマファイルを元に、モデル生成とテーブル作成をします。

モデルの作成

symfony doctrine:build-model
symfony cc

モデルクラスは /lib/doctrine/ 以下に生成されます。
User.class.phpがレコードクラス、UserTable.class.phpがテーブルクラスです。
ユーザスクリプトはこれらのクラスに記述します。

/lib/doctrine/generated/ 以下のファイルは自動的に更新されるので、触らないようにします。

モデルの再生成をした後は、キャッシュのクリアを忘れずに行います。

テーブルの作成

symfony doctrine:build-db app_name

build-dbの後にアプリケーション名の指定が必要です。
このタスクはすでにDB上に同名のテーブルがある場合に自動でテーブルをドロップしません。

以上でDoctrineを使ってテーブルにアクセスする準備は整いました。

次回以降、スキーマを修正して再度同じ手順を踏むには、まず既存テーブルをすべてドロップする必要がありますが、doctrine:drop-dbを行うと、テーブルのデータもすべて破棄されてしまいます。

そこで、いったんテーブルデータをダンプし、テーブルの作成、データのロードという手順を踏むことになります。

symfony doctrine:data-dump app_name dump_data.yml
symfony doctrine:drop-db --force app_name
symfony doctrine:build-all-load app_name

まず、/data/fixtures/dump_data.ymlファイルにデータがダンプされ、次にテーブルがドロップされます。
drop-dbタスクでは、テーブルを本当にドロップするかどうかをたずねられますが、--forceオプションでこの確認を無効にしています。
最後にbuild-all-loadタスクで、モデルを生成し、テーブルを作成し、ダンプしたデータを読み込みます。

タグ: ,

関連する投稿

その1で作ったスキーマに、リレーションの設定を追加します。

User:
<<略>>
  relations:
    Prefecture:
      local: prefecture_id
      foreign: id
      type: one
      foreignType: many
    Posts:
      class: Post
      local: id
      foreign: user_id
      type: many
      foreignType: one
      onDelete: CASCADE
  actAs:
    Timestampable:

relations: の後に、リレーション定義を書きます。
まずリンクする相手先のクラス名を書き、その次に、リレーションに使うカラム名を、元のクラス(local)、相手のクラス(foreign)の順に書きます。

次に、one-to-one、one-to-manyなどのレコード数の関係を書きます。
typeが元クラスから相手を見たときのレコードの数、foreignTypeが相手クラスから元クラスを見たときのレコードの数です。

Postsの例にあるように、リレーション名とクラス名を別々にすることも出来ます。

また、リレーションでonDelete: CASCADEを指定することで、親レコード(User)が削除された場合に、子レコード(Post)が削除されるように指定することが出来ます。

最後にこの例では、actAs: によってテンプレートの利用を宣言しています。
doctrineのテンプレートは、propelのビヘイビアと同じようなもので、
クラスにさまざまな振る舞いを追加できます。

例ではコアテンプレートのTimestampableによって、created_atupdated_atという二つのカラムが自動的に追加され、管理されます。

Timestampableのほかにも、いくつかデフォルトのテンプレートが用意されているほか、テンプレートは自分で作成することも出来ます。
Doctrineのマニュアルを参照

タグ: ,

関連する投稿

実際の開発ではこの方法でDBからスキーマを作るより、スキーマを書いて→モデルの作成→テーブルの作成という作業を繰り返し行っていくことになります。

スキーマファイルは /lib/config/doctrine 以下に置きます。
このディレクトリにあるすべてのファイルが処理対象になので、ファイルは複数あってもかまいません。
ファイルには好きな名前をつけることができます。
ファイルの書式はyamlなので、拡張子は.ymlにします。

複数のファイルに同じクラス名の定義を書くと、エラーの原因になるので、定義が重複しないように気をつけましょう。

以下のサンプルを使って、スキーマファイルの書き方を説明します。

---
User:
  tableName: site_users  #オプション
  columns:
    prefecture_id: integer
    name: string(255)
    email:
      type: string(255)
      notnull: true
    profile: string
    is_available:
      type: bool
      default: false

UserというのがDoctrineのクラス名になります。
同時に、CamelCaseで変換されて、テーブル名にもなります。
つまり、テーブル名はすべて小文字になり、途中にある大文字はハイフンと小文字に変換されます。

テーブル名はtableNameによって別に指定することも出来ます。

columns: の後に、カラム定義を書きます。
テーブルにはデフォルトでidというカラムが作成されるので、ここでプライマリキーは定義しません。

カラム名の後に直接型を書く方法と、型やデフォルト値などを分けて各方法があります。nameとemailを比較してください。

型がどのように変換されるかは実際に利用するDBMSによって異なります。
PostgreSQLでは、string(255)はvarchar(255)に、長さ指定の無いstringはtextに変換されます。

タグ: ,

関連する投稿

既存のデータベースからdoctrineのスキーマファイルを作成

symfony doctrine:build-schema shop app_name

スキーマファイルは /config/doctrine/schema.ymlとして出力されます。

スキーマファイルの先頭から二行目に、

---
detect_relations: true

を書き加えると、テーブルのリレーションを自動で判別してくれます。

ただ、この方法でスキーマファイルを作ると、記述が冗長になるのと、作成するたびに、自分で追加した変更内容がすべて消えるので、開発を進める過程で使うのには難があります。
ビヘイビアを追加したり、リレーションを手動で設定する必要がどうしても出てくるからです。

プロジェクト開始時に、既存のデータベースを取り込むのには便利です。

タグ: ,

関連する投稿