2011-08-10 17 views
1

コード内に「APIのような」レイヤーを作成して、より高度なコードへのデータベースアクセスを効果的に遮断したいと考えています。例えば、私は次の関数があるとします。Doctrine2エンティティを「無効にする」方法はありますか?

class MyApi { 
    private $my_user_id; 
    function getContacts() { 
     $contacts = $em->getRepository('Contacts')->findByOwner($this->my_user_id); 
     $em->clear(); 
     return $contacts; 
    } 
    function getGroups() { 
     $groups = $em->getRepository('Groups')->findByOwner($this->my_user_id); 
     //hydrate each group's contacts list 
     foreach ($groups as $group) { 
      $group->getContacts(); 
     } 
     $em->clear(); 
     return $groups; 
    } 
} 

を私は私の見解が誤って管理対象エンティティを変更することはできませんので、それらを返す前にEntityMangerからエンティティを切り離すために$をEM->クリア()を使用しています。しかし、2つの順次API関数が返すエンティティを比較したいときに問題が発生します。理想的には、私が含まれているために、ビュー/コントローラが欲しい:

$my_contacts = $myapi->getContacts(); 
$my_groups = $myapi->getGroups(); 

foreach($my_groups as $group) { 
    foreach ($my_contacts as $contact) { 
     if ($group->getContacts()->contains($contact)) { 
      echo "{$group->getName()} contains {$contact->getName()}!<br/>"; 
     } else { 
      echo "{$group->getName()} does not contain {$contact->getName()}!<br/>"; 
     } 
    } 
} 

をしかし、私はgetContacts API呼び出しの終わりにはEntityManagerから連絡先のすべてを外れているため、$group->getContacts()によって返されるオブジェクトは異なるです$api->getContacts()によって返されるものよりもPHPオブジェクトであるため、関数が正しく機能しません。

EntityManagerが提供するメリットを諦めることなく、実体を「読み取り専用」にする「defanging」オプションがありますか? (同じオブジェクトが同じデータベースエントリを表すすべての管理されたエンティティが、APIから返された後に関連付けられたオブジェクトをさらに水和することができるなど)

答えて

1

あなたの意見が変更を加えてデータベースにコミットしますか?あなたの意見がEMについて知らない(そしてそうすべきではない)場合、エンティティに加えられた変更はリクエストの最後に消えます。

私が考えることができる唯一の他の選択肢は、ビュースクリプトに供給されることになっているときに結果を配列として水和することです。しかし、それは多くの便利な機能を提供します。

+0

私は自分の見解が自分自身を洗い流すのではないと心配していますが、コントローラーが「ゲッター」APIアクションを呼び出し、返されたエンティティを変更してから、 EMをフラッシュすることを伴う。 2回目のAPI呼び出しでは、API呼び出しの間に意図しない変更が加えられ、意図した変更が書き込まれます。 APIの外では変更しないように注意してください。APIのポイントは、間違いから自分を守り、エンティティがEMにどのように関係しているか心配する必要がなくなります。 –

+0

別のオプションは、エンティティをビューに渡す前にデタッチすることです。もちろん、あなたはあなたが必要とするすべての団体を持ってきたことに気をつける必要があります。そして、B)あなたのデタッチ作業は、すべての団体にカスケードします。 – timdev

0

多分これは少し遅れているが、それはまだこの問題に答えを必要とする人のために役立ちます...

私はここで、ドメイン駆動設計原理が欠けていると思う:Command Query Separationを。すべてのオン
はあなたが唯一の方法の2種類持つことができるオブジェクト:心の中で適切なMVCを維持

doSomething() { 
    //this kind of method can change the internal state 
} 

getSomething() { 
    //this kind of method NEVER changes internal state 
} 

を、ビューは取得のみ-メソッド必要があるのと、彼らは事を変更することはできません。
エンティティを切り離す必要はなく、CQSとMVCだけを念頭に置いておくと心配はありません。