2014-03-25 3 views
0

ZF2와 Doctrine을 사용하여 두 개 이상의 테이블을 조인하고, 폼을 생성하고, 폼 입력/변경으로 모든 테이블을 업데이트하는 튜토리얼 또는 예제 모듈을 찾고 있습니다. (쿼리가 참여할 레코드를 찾지 못했을 때 연결된 테이블에 레코드를 추가하는 메소드가 포함 된 것을 찾는 데 보너스가 추가됩니다.)하나의 폼에서 ZF2와 Doctrine으로 두 테이블을 업데이트하십시오.

ZF2/Doctrine에서 복제하려고하는 패턴은 무언가입니다 예 : members 테이블과 personal_info 테이블이 있습니다. 테이블 간에는 일대일 관계가 있지만, 회원의 일부분 만 개인 정보를 기록하면되므로 부담을 줄이기 위해 필요에 따라 일치하는 레코드를 personal_info 테이블에 추가합니다. 우리 양식에는 두 테이블의 데이터를 업데이트하는 상자가 포함됩니다. phone 입력은 members 테이블의 레코드를 업데이트하고 spouse 입력은 personal_info 테이블의 레코드를 업데이트합니다.

PHP 버전은 양식을 구성하기 위해 다음 단계를 수행 할 수 있습니다. 1) personal_info 테이블을 쿼리하여 사용자 제공 member id에 대한 레코드가 존재하는지 확인합니다. 2) 존재하지 않으면 personal_info에 새 레코드를 추가하십시오. 3) 테이블을 조인하는 질의를 생성한다; 4) 쿼리의 데이터로 채워진 폼을 생성합니다. 폼의 사용자 업데이트에 의해 트리거되는 동작은 1) members 테이블을 업데이트하고 2) personal_info 테이블을 업데이트하는 두 단계가 있습니다.

자습서와 예제를 검색 할 때 필요한 경우 두 테이블을 하나의 양식에서 업데이트하거나 누락 된 레코드를 조인 된 테이블에 추가하는 것을 발견하지 못했습니다.

편집 : 샘의 제안에 따라

, 나는 DoctrineModule의 예제를 따라했지만 나는 그것이 작동 할 수 없습니다. 엔터티, 필드 세트, 폼, 뷰 및 컨트롤러를 설정했지만 데이터가 데이터베이스에서 렌더링 된 폼으로 전달되지 않습니다. 갱신 양식이나 작성 양식 모두 데이터베이스를 갱신하지 않습니다. 데이터베이스 데이터는 업데이트 양식 요소의 값 속성에 제공되지 않습니다.

URL 라우터에 존재하지 않는 ID를 넣으면 오류가 발생하기 때문에 데이터가 데이터베이스에서 추출된다는 것을 알고 있습니다. 엔티티와 필드 세트, 필드 세트와 양식, 제어기 또는 뷰에서 문제가 있는지 여부를 구분할 수 없습니다.여기 내 파일은 다음과 같습니다

회원 법인 :

<?php 

namespace Members\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use Members\Entity\PersonalInfo; 

/** 
* Members 
* 
* @ORM\Entity 
* @ORM\Table(name="members") 
* @property string $memberFirstName 
* @property string $memberLastName 
* @property int $memberID 
*/ 
class Member 
{ 
    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer"); 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $memberID; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $memberFirstName; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $memberLastName; 

    /** 
    * @ORM\OneToMany(targetEntity="Members\Entity\PersonalInfo", mappedBy="member", cascade={"persist"}) 
    */ 
    protected $personalInfo; 

    /** 
    * initialize collections 
    */ 
    public function __construct() 
    { 
     $this->personalInfo = new ArrayCollection(); 
    } 

    /** 
    * Get MemberID 
    * 
    * @return integer 
    */ 
    public function getMemberID() 
    { 
     return $this->memberID; 
    } 

    /** 
    * Get MemberLastName 
    * 
    * @return string 
    */ 
    public function getMemberLastName() 
    { 
     return $this->memberLastName; 
    } 

    /** 
    * Set MemberLastName 
    * 
    * @param string $memberLastName 
    */ 
    public function setMemberLastName($memberLastName) 
    { 
     $this->memberLastName = $memberLastName; 

     return $this; 
    } 

    /** 
    * Get MemberFirstName 
    * 
    * @return string 
    */ 
    public function getMemberFirstName() 
    { 
     return $this->memberFirstName; 
    } 

    /** 
    * Set MemberFirstName 
    * 
    * @param string $memberFirstName 
    */ 
    public function setMemberFirstName($memberFirstName) 
    { 
     $this->memberFirstName = $memberFirstName; 

     return $this; 
    } 

    /** 
    * @param Collection $personalInfo 
    */ 
    public function addPersonalInfo(Collection $personalInfo) 
    { 
     foreach ($personalInfo as $memberPersonalInfo) { 
      $memberPersonalInfo->setMember($this); 
      $this->personalInfo->add($memberPersonalInfo); 
     } 
    } 

    /** 
    * @param Collection $personalInfo 
    */ 
    public function removePersonalInfo(Collection $personalInfo) 
    { 
     foreach ($personalInfo as $memberPersonalInfo) { 
      $memberPersonalInfo->setMember(null); 
      $this->personalInfo->removeElement($memberPersonalInfo); 
     } 
    } 

    /** 
    * @return Collection 
    */ 
    public function getPersonalInfo() 
    { 
     return $this->personalInfo; 
    } 

} 

PersonalInfo 법인 :

<?php 

namespace Members\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Members\Entity\Member; 

/** 
* Personal Info 
* 
* @ORM\Entity 
* @ORM\Table(name="members_personal") 
* @property string $spouse 
* @property string $hobbies 
* @property int $memberID 
* @property int $personalInfoID 
*/ 
class PersonalInfo 
{ 
    /** 
    * @ORM\Column(type="integer"); 
    */ 
    protected $memberID; 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer"); 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $personalInfoID; 

    /** 
    * @ORM\ManyToOne(targetEntity="Members\Entity\Member", inversedBy="personalInfo") 
    * @ORM\JoinColumn(name="memberID", referencedColumnName="memberID") 
    */ 
    protected $member; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $spouse; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $hobbies; 


    /** 
    * Get PersonalInfoID 
    * 
    * @return integer 
    */ 
    public function getPersonalInfoID() 
    { 
     return $this->personalInfoID; 
    } 

    /** 
    * Allow null to remove association 
    * 
    * @param Member $member 
    */ 
    public function setMember(Member $member = null) 
    { 
     $this->member = $member; 
    } 

    /** 
    * @return Member 
    */ 
    public function getMember() 
    { 
     return $this->member; 
    } 

    /** 
    * Set Spouse 
    * 
    * @param string $spouse 
    */ 
    public function setSpouse($spouse) 
    { 
     $this->spouse = $spouse; 
    } 

    /** 
    * Get Spouse 
    * 
    * @return string 
    */ 
    public function getSpouse() 
    { 
     return $this->spouse; 
    } 

    /** 
    * Set Hobbies 
    * 
    * @param string $hobbies 
    */ 
    public function setHobbies($hobbies) 
    { 
     $this->hobbies = $hobbies; 
    } 

    /** 
    * Get Hobbies 
    * 
    * @return string 
    */ 
    public function getHobbies() 
    { 
     return $this->hobbies; 
    } 

} 

MemberFieldset :

<?php 

namespace Members\Form; 

use Members\Entity\Member; 
use Doctrine\Common\Persistence\ObjectManager; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 
use Zend\Form\Fieldset; 
use Zend\InputFilter\InputFilterProviderInterface; 

class MemberFieldset extends Fieldset implements InputFilterProviderInterface 
{ 
    public function __construct(ObjectManager $objectManager) 
    { 
     parent::__construct('member'); 

     $this->setHydrator(new DoctrineHydrator($objectManager, 'Members\Entity\Member')) 
      ->setObject(new Member()); 

     $this->add(array(
      'type' => 'Zend\Form\Element\Text', 
      'name' => 'memberID', 
      'attributes' => array(
       'type' => 'hidden', 
      ), 
     )); 

     $this->add(array(
      'type' => 'Zend\Form\Element\Text', 
      'name' => 'memberLastName', 
      'attributes' => array(
       'required' => 'required', 
       'type' => 'text', 
      ), 
      'options' => array(
       'label' => 'Last Name', 
      ), 
     )); 

     $this->add(array(
      'type' => 'Zend\Form\Element\Text', 
      'name' => 'memberFirstName', 
      'attributes' => array(
       'required' => 'required', 
       'type' => 'text', 
      ), 
      'options' => array(
       'label' => 'First Name', 
      ), 
     )); 

     $personalInfoFieldset = new PersonalInfoFieldset($objectManager); 
     $this->add(array(
      'type' => 'Zend\Form\Element\Collection', 
      'name' => 'personalInfo', 
      'options' => array(
       'count'   => 1, 
       'target_element' => $personalInfoFieldset 
      ) 
     )); 

    } 

    public function getInputFilterSpecification() 
    { 
     return array(
      'memberID' => array(
       'required' => true 
      ), 
     ); 
     return array(
      'memberLastName' => array(
       'required' => true 
      ), 
     ); 
     return array(
      'memberFirstName' => array(
       'required' => true 
      ), 
     ); 
    } 

} 

PersonalInfoFieldset :

<?php 

namespace Members\Form; 

use Members\Entity\PersonalInfo; 
use Doctrine\Common\Persistence\ObjectManager; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 
use Zend\Form\Fieldset; 
use Zend\InputFilter\InputFilterProviderInterface; 

class PersonalInfoFieldset extends Fieldset implements InputFilterProviderInterface 
{ 
    public function __construct(ObjectManager $objectManager) 
    { 
     parent::__construct('personal-info'); 

     $this->setHydrator(new DoctrineHydrator($objectManager, 'Members\Entity\PersonalInfo')) 
      ->setObject(new PersonalInfo()); 

     $this->add(array(
      'type' => 'Zend\Form\Element\Text', 
      'name' => 'personalInfoID', 
      'attributes' => array(
       'type' => 'hidden', 
      ), 
     )); 

     $this->add(array(
      'name' => 'spouse', 
      'type' => 'Zend\Form\Element\Text', 
      'attributes' => array(
       'required' => 'required', 
       'type' => 'text', 
      ), 
      'options' => array(
       'label' => 'Page Title', 
      ), 
     )); 

     $this->add(array(
      'name' => 'hobbies', 
      'type' => 'Zend\Form\Element\Text', 
      'attributes' => array(
       'required' => 'required', 
       'type' => 'text', 
      ), 
      'options' => array(
       'label' => 'Page Name', 
      ), 
     )); 

    } 
    public function getInputFilterSpecification() 
    { 
     return array(
      'personalInfoID' => array(
       'required' => true 
      ), 
     ); 
     return array(
      'spouse' => array(
       'required' => true 
      ), 
     ); 
     return array(
      'hobbies' => array(
       'required' => true 
      ), 
     ); 
    } 

} 

CreateMemberForm :

<?php 

namespace Members\Form; 

use Doctrine\Common\Persistence\ObjectManager; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 
use Zend\Form\Form; 

class CreateMemberForm extends Form 
{ 
    public function __construct(ObjectManager $objectManager) 
    { 
     parent::__construct('update-member-form'); 

     // The form will hydrate an object of type "Member" 
     $this->setHydrator(new DoctrineHydrator($objectManager, 'Members\Entity\Member')); 

     // Add the user fieldset, and set it as the base fieldset 
     $memberFieldset = new MemberFieldset($objectManager); 
     $memberFieldset->setUseAsBaseFieldset(true); 
     $this->add($memberFieldset); 

     // submit elements 
     $this->setAttribute('method', 'post'); 

     $this->add(array(
      'name' => 'memberID', 
      'attributes' => array(
       'type' => 'hidden', 
      ), 
     )); 
     $this->add(array(
      'name' => 'memberLastName', 
      'attributes' => array(
       'id' => 'memberLastName', 
       'type' => 'text', 
       'class' => 'col-lg-10', 
      ), 
      'options' => array(
       'label' => 'Last Name', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'memberFirstName', 
      'attributes' => array(
       'id' => 'memberFirstName', 
       'type' => 'text', 
       'class' => 'col-lg-10', 
      ), 
      'options' => array(
       'label' => 'First Name', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'spouse', 
      'attributes' => array(
       'id' => 'spouse', 
       'type' => 'text', 
       'class' => 'col-lg-10', 
      ), 
      'options' => array(
       'label' => 'Spouse', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'submit', 
      'attributes' => array(
       'id' => 'submit', 
       'type' => 'submit', 
       'value' => 'Go', 
       'id' => 'submitbutton', 
      ), 
     )); 

     // Optionally set your validation group here 
    } 

} 

UpdateMemberForm :

<?php 

namespace Members\Form; 

use Doctrine\Common\Persistence\ObjectManager; 
use DoctrineModule\Stdlib\Hydrator\DoctrineObject as DoctrineHydrator; 
use Zend\Form\Form; 

class UpdateMemberForm extends Form 
{ 
    public function __construct(ObjectManager $objectManager) 
    { 
     parent::__construct('update-member-form'); 

     // The form will hydrate an object of type "Member" 
     $this->setHydrator(new DoctrineHydrator($objectManager, 'Members\Entity\Member')); 

     // Add the user fieldset, and set it as the base fieldset 
     $memberFieldset = new MemberFieldset($objectManager); 
     $memberFieldset->setUseAsBaseFieldset(true); 
     $this->add($memberFieldset); 

     // submit elements 
     $this->setAttribute('method', 'post'); 

     $this->add(array(
      'name' => 'memberID', 
      'attributes' => array(
       'type' => 'hidden', 
      ), 
     )); 
     $this->add(array(
      'name' => 'memberLastName', 
      'attributes' => array(
       'id' => 'memberLastName', 
       'type' => 'text', 
       'class' => 'col-lg-9', 
      ), 
      'options' => array(
       'label' => 'Last Name', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'memberFirstName', 
      'attributes' => array(
       'id' => 'memberFirstName', 
       'type' => 'text', 
       'class' => 'col-lg-9', 
      ), 
      'options' => array(
       'label' => 'First Name', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'spouse', 
      'attributes' => array(
       'id' => 'spouse', 
       'type' => 'text', 
       'class' => 'col-lg-9', 
      ), 
      'options' => array(
       'label' => 'Spouse', 
       'label_attributes' => array(
        'class' => 'col-lg-2 control-col-label' 
       ), 
      ), 
     )); 

     $this->add(array(
      'name' => 'submit', 
      'attributes' => array(
       'id' => 'submit', 
       'type' => 'submit', 
       'value' => 'Go', 
       'id' => 'submitbutton', 
      ), 
     )); 

     // Optionally set your validation group here 
    } 



} 

MemberController :

<?php 

namespace Members\Controller; 

use Zend\Mvc\Controller\AbstractActionController; 
use Zend\View\Model\ViewModel; 
use Members\Entity\Member; 
use Members\Form\CreateMemberForm; 
use Members\Form\UpdateMemberForm; 
use Doctrine\ORM\EntityManager; 

class MemberController extends AbstractActionController 
{ 
    /** 
    * @var Doctrine\ORM\EntityManager 
    */ 
    protected $em; 

    public function setEntityManager(EntityManager $em) 
    { 
     $this->em = $em; 
    } 

    public function getEntityManager() 
    { 
     if (null === $this->em) { 
      $this->em = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 
     } 
     return $this->em; 
    } 

    // ... // 

    public function createAction() 
    { 
     // Get ObjectManager from the ServiceManager 
     $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 

     // Create the form and inject the ObjectManager 
     $form = new CreateMemberForm($objectManager); 

     // Create a new, empty entity and bind it to the form 
     $member = new Member(); 
     $form->bind($member); 

     if ($this->request->isPost()) { 
      $form->setData($this->request->getPost()); 

      if ($form->isValid()) { 
       $objectManager->persist($member); 
       $objectManager->flush(); 
      } 
     } 

     return array('form' => $form); 
    } 

    public function updateAction() 
    { 
     $memberID = (int)$this->getEvent()->getRouteMatch()->getParam('memberID'); 
     if (!$memberID) { 
      return $this->redirect()->toRoute('members', array('action'=>'create')); 
     } 
     $member = $this->getEntityManager()->find('Members\Entity\Member', $memberID); 

     // Get your ObjectManager from the ServiceManager 
     $objectManager = $this->getServiceLocator()->get('Doctrine\ORM\EntityManager'); 

     // Create the form and inject the ObjectManager 
     $form = new UpdateMemberForm($objectManager); 
     $form->setBindOnValidate(false); 
     $form->bind($member); 
     $form->get('submit')->setAttribute('label', 'Update'); 

     $request = $this->getRequest(); 
     if ($request->isPost()) { 
      $form->setData($request->getPost()); 
      if ($form->isValid()) { 
       $form->bindValues(); 
       $this->getEntityManager()->flush(); 

       // Redirect to list of members 
       return $this->redirect()->toRoute('members'); 
      } 
     } 

     return array(
      'memberID' => $memberID, 
      'form' => $form, 
     ); 
    } 

    // ... // 

} 

update.phtml :

<?php 
$title = 'Update Member'; 
$this->headTitle($title); 
?> 
<h1><?php echo $this->escapeHtml($title); ?></h1> 

<?php 
$form = $this->form; 
$form->setAttribute('action', 
    $this->url('members', array('action' => 'update', 'memberID'=>$this->memberID))); 
$form->prepare(); 

echo $this->form()->openTag($form); 
echo $this->formHidden($form->get('memberID')); 
echo $this->formRow($form->get('memberFirstName')) . "<br clear='both'/>"; 
echo $this->formRow($form->get('memberLastName')) . "<br clear='both'/>"; 
echo $this->formRow($form->get('spouse')) . "<br clear='both'/>"; 
echo $this->formInput($form->get('submit')); 
echo $this->form()->closeTag($form); 

답변

0

두 테이블은 관계가 있으므로 부모 개체는 여전히 member이라고 가정합니다. 이를 염두에두고 여전히 두 개의 Fieldset 요소를 만들어야합니다. 하나는 member의 구조와 일치하고 다른 하나는 personal_info의 데이터와 일치합니다. 나중에 하위 필드 집합으로 MemberFieldset에 추가됩니다.

그건 사실입니다. DoctrineObject (Hydrator)은 새로운 항목 인 경우 ID 매핑을 처리 할 수 ​​있어야합니다. 편집 항목이라면 ID 데이터가 거기에 있습니다. 실제로는 DoctrineModule /docs에 의해 주어진 예제와 다른 거래가 아닙니다.

+0

감사합니다. Sam. 이 질문에 대한 우연의 일치는 무엇입니까? 블로그 게시물 "블로그 응용 프로그램 제 1 부 - Zend Framework 2에서 Doctrine 2로 작업하기"를 수행하고 관계형 항목에 대한 다음 단계를 찾은 후 작성했습니다. – jcropp

+0

DoctrineModule 저장소에서 hydrator 문서를 따라했지만 계속 중단되었습니다. 먼저, 문서의 기반이되는 버전과 내가 가지고있는 버전이 다르다는 것을 발견하는 데 어느 정도 시간이 걸렸습니다. 필드 집합에서이 코드는'$ this-> setHydrator (new DoctrineHydrator ($ objectManager))'클래스에'$ this-> setHydrator (new DoctrineHydrator ($ this objectManager, 'this/class/name')) 클래스를 포함해야합니다. ' – jcropp

+0

그럼'function editAction()'에서 문제가 발생했습니다. '$ blogPost = $ this-> userService-> get ($ this-> params ('blogPost_id'));에서 시스템은 userService를 좋아하지 않습니다. 'blogPost_id'는 존재하지 않습니다. – jcropp

관련 문제