前回に引き続きDoctrineのチュートリアルを和訳しつつ進めていきます。
(参考: Getting Started with Doctrine — Doctrine 2 ORM 2 documentation)
・コレクションに対するsaveやupdateはそのコレクションを所有しているエンティティがsave, updateされたときに実行される。
・saveしているエンティティの反対のエンティティはコレクションを変更する操作が実行されたりはしない
・1対1のリレーションにおいて、相手のエンティティの外部キーを所有しているほうが常に所有側となる。
・many-to-manyのリレーションにおいては両方が所有側となる。しかし、bi-directionalな多対多の関連は片方のみに許される。
・多対多のリレーションにおいて、「多」側はデフォルトで所有側となる、これはそちらが外部キーを持っているからである。
・1対多ではデフォルトで逆になる。なぜなら「多」側で外部キーをsaveするからである。もし、多対多によってテーブルをjoinし、片方にのみユニークな値を許可している場合、1対多のリレーションは所有側でのみ可能である。
このUsersとBugsの場合、ユーザから認定されたものと報告されたバグに対して、参照しあう関係になっていて、bi-directionalになっています。なので、これらを以下のように変更します
フィールド定義の後にはユーザエンティティへの2つの参照が定義されています。これらはmany-to-oneタグで作成されています。関連するエンティティのクラス名はtarget-entity属性で指定されていて、これはDBマッパーがほかのテーブルにアクセスするには十分な情報です。Bi-directionalなリレーションにおいてreporterとengineerは所有者側であるので、inversed-by属性も指定する必要があります。これはリレーションにおいて所有される側のフィールド名を指定する必要があります。次の例ではinversed-by属性はその対称物であるmapped-byがあることも見ていくことにします。
最後はBug#productsコレクションを定義していきます。これは特定のバグが起きているすべてのプロダクトを意味しています。再び、target-entityとfield属性をmany-to-manyのタグで定義する必要があります。
最後にユーザエンティティを定義していきます
ここでは新しくone-to-manyタグに言及していきます。そしてこれまでの所有側とその逆について思い出しておく必要があります。今、repotedBugsとassignedBugsは所有側とは逆にリレーションされています。これはjoinについての詳細はすでに所有側で定義されていることを示しています。
つまり、所有側であるBugクラスのプロパティを示してあげるだけでいいのです。
この例はmetadata definition languageの最も基本的な手法になります。
Databaseを更新します。
以下の様な出力結果が確認できました。
Updating database schema...
Database schema updated successfully! "7" queries were executed
これによって、bugs, users, bug_productテーブルが出来たことが確認できました。
Implementing more Requirements
・さらなる要求を実装していきます
まず、create_userエンティティが必要です。
次を実行します
実行すると
PHP Fatal error: Class 'ArrayCollection' not found in /Library/WebServer/Documents/doctrine-orm/src/User.php on line 33
とerrorを吐かれてしまいました。
さっきのコードで以下をなくしたことが原因でした。コードを消す時点でおかしいなと思っていたので、すぐ追加します。__construct()内で使ってるんだから当然ですよね。。。
use Doctrine\Common\Collections\ArrayCollection;
再度実行すると以下のように出力されbeberleiという国籍も想像できない人間がユーザに追加されます。。。
Created User with ID1
これで、バグを作成するデータができ、このシナリオは次のようになるでしょう。
ここではユーザとプロダクトは1つずつしかないので、次のようなスクリプトを実行してみます。
ここで初めてエンティティマネージャの呼び出しAPIを利用していて、EntityManager#find($name, $id)を呼び出し、プライマリキーによって、実行された1つのインスタンスが返されていることがわかります。
加えて、persistとflushパターンによってDBにBugが保存されていることも確認できます。
チュートリ(3)につづく