Symfony FOS Rest Bundle Api呼叫多对多关系


Symfony FOS Rest Bundle Api Call Many to Many Relationship

我似乎有问题。我相信它有一个非常简单的解决方案。我有一个API,它使用FOS Rest捆绑包。我有一个调用,它向postCreateTimesheetAction发送POST请求(request$request),后者在时间表表中创建一个空行。我有另一个调用patchTimesheetAction,它稍后会向表中添加一些数据。好的,一切都很好。我有另一个调用patchCareoptionAction(Timesheet$Timesheet),它在一个表中创建了一行,该表具有从CareOptions.php(下图)和Timesheet.php(下图。我会把它们贴在下面这里:

在时间表表中创建一个空白的新时间表行:(timesheet.php)

curl-H"接受:application/json"-H"内容类型:application/json"-i-X POST-d'{"homecare_homecarebundle_timesheet":"}'www.hc-timeeets-demo.com/app_dev.php/api/v1/create/timesheet

使用数据更新时间表行:

curl-i-H"接受:application/json"-H"内容类型:application/json"-d'{"homecare_homecarebundle_timesheet":{"代理":"157","收件人":"154","主成分分析":"16","服务":"6"}}'-X PATCH www.hc-timesheets-demo.com/app_dev.php/api/v1/timesheet/31

并最终创建了多对多关系:

curl-i-H"接受:application/json"-H"内容类型:application/json"-d'{"homecare_homecarebundle_timesheet":{"careOption":[456457]}}'-X PATCH www.hc-timeeets-demo.com/app_dev.php/api/v1/caroption/31

请注意补丁请求末尾的31。这是从第一个api调用在表中创建的时间表的id。让我们来回答我的问题吧!每当我调用第三个api调用时,我都会成功地在表中创建多对多行。但当我再次调用它时,它不会用新的行替换旧的行。它只是向表中添加了更多的行。我希望更新多对多表行,去掉旧的行。我需要先把它们删除吗?让我再解释一下。如果您在第三次api调用中看到,我将在时间表中添加2个careOptions:(careOptions 456和457)。如果我再打一次,比方说我想加458和459。我想要456和457自动删除并离开。请有人帮我??!!

以下是多对多关系的拥有方

<?php
//src/Homecare/HomecareBundle/Entity/CareOptions.php
namespace Homecare'HomecareBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use Doctrine'Common'Collections'ArrayCollection;
/**
 * CareGoals
 *
 * @ORM'Table(name="careoptions")
 * @ORM'Entity(repositoryClass="Homecare'HomecareBundle'Entity'Repository'CareOptionsRepository")
 */
class CareOptions
{
/**
 * @var integer
 *
 * @ORM'Column(name="id", type="integer")
 * @ORM'Id
 * @ORM'GeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @ORM'OneToMany(targetEntity="CareOptionsTimesheets", mappedBy="careOption")
     */
        private $care_options_timesheets;

/**
 * @var string
 *
 * @ORM'Column(name="care_option", type="string", length=255)
 */
    private $careOption;

    /**
    * @ORM'ManyToMany(targetEntity="CareGoals", mappedBy="careOption")
    */
    private $careGoals;


    /**
    * @ORM'ManyToMany(targetEntity="Timesheet", inversedBy="careOption", cascade={"persist"})
    */
    private $timesheet;


    public function __construct()
     {
         $this->care_options_timesheets = new ArrayCollection();
                 $this->timesheet = new ArrayCollection();
     }

/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}



    //add a to string method so that the object can be displayed in the twig template
    /*
    public function __toString()
            {
                return $this->getCareGoal();
            }
    */

/**
 * Set careOption
 *
 * @param string $careOption
 * @return CareOptions
 */
public function setCareOption($careOption)
{
    $this->careOption = $careOption;
    return $this;
}
/**
 * Get careOption
 *
 * @return string 
 */
public function getCareOption()
{
    return $this->careOption;
}
/**
 * Add care_options_timesheets
 *
 * @param 'Homecare'HomecareBundle'Entity'CareOptions_Timesheets $careOptionsTimesheets
 * @return CareOptions
 */
public function addCareOptionsTimesheet('Homecare'HomecareBundle'Entity'CareOptionsTimesheets $careOptionsTimesheets)
{
    $this->care_options_timesheets[] = $careOptionsTimesheets;
    return $this;
}
/**
 * Remove care_options_timesheets
 *
 * @param 'Homecare'HomecareBundle'Entity'CareOptions_Timesheets $careOptionsTimesheets
 */
public function removeCareOptionsTimesheet('Homecare'HomecareBundle'Entity'CareOptionsTimesheets $careOptionsTimesheets)
{
    $this->care_options_timesheets->removeElement($careOptionsTimesheets);
}
/**
 * Get care_options_timesheets
 *
 * @return 'Doctrine'Common'Collections'Collection 
 */
public function getCareOptionsTimesheets()
{
    return $this->care_options_timesheets;
}
/**
 * Add careGoals
 *
 * @param 'Homecare'HomecareBundle'Entity'CareGoals $careGoals
 * @return CareOptions
 */
public function addCareGoal('Homecare'HomecareBundle'Entity'CareGoals $careGoals)
{
    $this->careGoals[] = $careGoals;
    return $this;
}
/**
 * Remove careGoals
 *
 * @param 'Homecare'HomecareBundle'Entity'CareGoals $careGoals
 */
public function removeCareGoal('Homecare'HomecareBundle'Entity'CareGoals $careGoals)
{
    $this->careGoals->removeElement($careGoals);
}
/**
 * Get careGoals
 *
 * @return 'Doctrine'Common'Collections'Collection 
 */
public function getCareGoals()
{
    return $this->careGoals;
}

    public function __toString() {
        return $this->getCareOption();
    }

/**
 * Add timesheet
 *
 * @param 'Homecare'HomecareBundle'Entity'Timesheet $timesheet
 * @return CareOptions
 */
public function addTimesheet('Homecare'HomecareBundle'Entity'Timesheet $timesheet)
{
    $this->timesheet[] = $timesheet;
    return $this;
}
/**
 * Remove timesheet
 *
 * @param 'Homecare'HomecareBundle'Entity'Timesheet $timesheet
 */
public function removeTimesheet('Homecare'HomecareBundle'Entity'Timesheet $timesheet)
{
    $this->timesheet->removeElement($timesheet);
}
/**
 * Get timesheet
 *
 * @return 'Doctrine'Common'Collections'Collection 
 */
public function getTimesheet()
{
    return $this->timesheet;
}
}

这是多对多关系的另一面:

<?php
//src/Homecare/HomecareBundle/Entity/Timesheet.php
namespace Homecare'HomecareBundle'Entity;
use Doctrine'ORM'Mapping as ORM;
use JMS'Serializer'Annotation'Type;
use JMS'Serializer'Annotation'SerializedName;
/**
 * Timesheet
 *
 * @ORM'Table(name="timesheet")
 * @ORM'Entity(repositoryClass="Homecare'HomecareBundle'Entity'Repository'TimesheetRepository")
 */
class Timesheet
{
/**
 * @var integer
 *
 * @ORM'Column(name="id", type="integer")
 * @ORM'Id
 * @ORM'GeneratedValue(strategy="AUTO")
     * @Type("integer")
     * @SerializedName("id")
 */
private $id;

/**
 * @ORM'ManyToOne(targetEntity="Agency", inversedBy="actualTimesheets")
     * @ORM'JoinColumn(name="agency_id", referencedColumnName="id")
     * @Type("Homecare'HomecareBundle'Entity'Agency")
     * @SerializedName("agency")
 */
private $agency;

/**
 * @ORM'ManyToOne(targetEntity="Recipient", inversedBy="actualTimesheets")
     * @ORM'JoinColumn(name="recipient_id", referencedColumnName="id")
     * @Type("Homecare'HomecareBundle'Entity'Recipient")
     * @SerializedName("recipient")
 */
private $recipient;

/**
 * @ORM'ManyToOne(targetEntity="Pca", inversedBy="actualTimesheets")
     * @ORM'JoinColumn(name="pca_id", referencedColumnName="id")
     * @Type("Homecare'HomecareBundle'Entity'Pca")
     * @SerializedName("pca")
 */
private $pca;

/**
 * @ORM'ManyToOne(targetEntity="Services", inversedBy="actualTimesheets")
     * @ORM'JoinColumn(name="service_id", referencedColumnName="id")
     * @Type("Homecare'HomecareBundle'Entity'Services")
     * @SerializedName("service")
 */
private $service;


    /**
    * @ORM'Column(name="continueTimesheetNumber",type="integer",nullable=true)
    * @Type("integer")
    * @SerializedName("continueTimesheetNumber")
    */
    private $continueTimesheetNumber;


    /**
    * @ORM'ManyToOne(targetEntity="VisitRatios", inversedBy="timesheets")
    * @Type("Homecare'HomecareBundle'Entity'VisitRatios")
    * @SerializedName("visitRatio")
    */
    private $visitRatio;


/**
 * @ORM'ManyToOne(targetEntity="TimeIn", inversedBy="timesheets")
     * @Type("Homecare'HomecareBundle'Entity'TimeIn")
     * @SerializedName("timeIn")
 */
private $timeIn;


/**
 * @ORM'ManyToOne(targetEntity="TimeOut", inversedBy="timesheets")
     * @Type("Homecare'HomecareBundle'Entity'TimeOut")
     * @SerializedName("timeOut")
 */
private $timeOut;


/**
 * @ORM'ManyToOne(targetEntity="Files", inversedBy="timesheets")
     * @Type("Homecare'HomecareBundle'Entity'Files")
     * @SerializedName("file")
 */
private $file;

    /**
    * @ORM'ManyToMany(targetEntity="CareOptions", mappedBy="timesheet", cascade={"persist"})
    * @Type("Homecare'HomecareBundle'Entity'CareOptions")
    * @SerializedName("careOption")
    */
    private $careOption;


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}


/**
 * Set agency
 *
 * @param 'Homecare'HomecareBundle'Entity'Agency $agency
 * @return Timesheet
 */
public function setAgency('Homecare'HomecareBundle'Entity'Agency $agency = null)
{
    $this->agency = $agency;
    return $this;
}
/**
 * Get agency
 *
 * @return 'Homecare'HomecareBundle'Entity'Agency 
 */
public function getAgency()
{
    return $this->agency;
}
/**
 * Set recipient
 *
 * @param 'Homecare'HomecareBundle'Entity'Recipient $recipient
 * @return Timesheet
 */
public function setRecipient('Homecare'HomecareBundle'Entity'Recipient $recipient = null)
{
    $this->recipient = $recipient;
    return $this;
}
/**
 * Get recipient
 *
 * @return 'Homecare'HomecareBundle'Entity'Recipient 
 */
public function getRecipient()
{
    return $this->recipient;
}
/**
 * Set pca
 *
 * @param 'Homecare'HomecareBundle'Entity'Pca $pca
 * @return Timesheet
 */
public function setPca('Homecare'HomecareBundle'Entity'Pca $pca = null)
{
    $this->pca = $pca;
    return $this;
}
/**
 * Get pca
 *
 * @return 'Homecare'HomecareBundle'Entity'Pca 
 */
public function getPca()
{
    return $this->pca;
}
/**
 * Set service
 *
 * @param 'Homecare'HomecareBundle'Entity'Services $service
 * @return Timesheet
 */
public function setService('Homecare'HomecareBundle'Entity'Services $service = null)
{
    $this->service = $service;
    return $this;
}
/**
 * Get service
 *
 * @return 'Homecare'HomecareBundle'Entity'Services 
 */
public function getService()
{
    return $this->service;
}


/**
 * Set continueTimesheetNumber
 *
 * @param integer $continueTimesheetNumber
 * @return Timesheet
 */
public function setContinueTimesheetNumber($continueTimesheetNumber)
{
    $this->continueTimesheetNumber = $continueTimesheetNumber;
    return $this;
}
/**
 * Get continueTimesheetNumber
 *
 * @return integer 
 */
public function getContinueTimesheetNumber()
{
    return $this->continueTimesheetNumber;
}
/**
 * Set visitRatio
 *
 * @param 'Homecare'HomecareBundle'Entity'VisitRatios $visitRatio
 * @return Timesheet
 */
public function setVisitRatio('Homecare'HomecareBundle'Entity'VisitRatios $visitRatio = null)
{
    $this->visitRatio = $visitRatio;
    return $this;
}
/**
 * Get visitRatio
 *
 * @return 'Homecare'HomecareBundle'Entity'VisitRatios 
 */
public function getVisitRatio()
{
    return $this->visitRatio;
}
/**
 * Set timeIn
 *
 * @param 'Homecare'HomecareBundle'Entity'TimeIn $timeIn
 * @return Timesheet
 */
public function setTimeIn('Homecare'HomecareBundle'Entity'TimeIn $timeIn = null)
{
    $this->timeIn = $timeIn;
    return $this;
}
/**
 * Get timeIn
 *
 * @return 'Homecare'HomecareBundle'Entity'TimeIn 
 */
public function getTimeIn()
{
    return $this->timeIn;
}
/**
 * Set timeOut
 *
 * @param 'Homecare'HomecareBundle'Entity'TimeOut $timeOut
 * @return Timesheet
 */
public function setTimeOut('Homecare'HomecareBundle'Entity'TimeOut $timeOut = null)
{
    $this->timeOut = $timeOut;
    return $this;
}
/**
 * Get timeOut
 *
 * @return 'Homecare'HomecareBundle'Entity'TimeOut 
 */
public function getTimeOut()
{
    return $this->timeOut;
}
/**
 * Set file
 *
 * @param 'Homecare'HomecareBundle'Entity'Files $file
 * @return Timesheet
 */
public function setFile('Homecare'HomecareBundle'Entity'Files $file = null)
{
    $this->file = $file;
    return $this;
}
/**
 * Get file
 *
 * @return 'Homecare'HomecareBundle'Entity'Files 
 */
public function getFile()
{
    return $this->file;
}
/**
 * Constructor
 */
public function __construct()
{
    $this->careOption = new 'Doctrine'Common'Collections'ArrayCollection();
}


/**
 * Add careOption
 *
 * @param 'Homecare'HomecareBundle'Entity'CareOptions $careOption
 * @return Timesheet
 */
public function addCareOption('Homecare'HomecareBundle'Entity'CareOptions $careOption)
{
          $careOption->addTimesheet( $this );
    $this->careOption[] = $careOption;
    return $this;
}
/**
 * Remove careOption
 *
 * @param 'Homecare'HomecareBundle'Entity'CareOptions $careOption
 */
public function removeCareOption('Homecare'HomecareBundle'Entity'CareOptions $careOption)
{
    $this->careOption->removeElement($careOption);
}
/**
 * Get careOption
 *
 * @return 'Doctrine'Common'Collections'Collection 
 */
public function getCareOption()
{
    return $this->careOption;
}
}

这是formBuilder时间表类型.php

<?php
//src/Homecare/HomecareBundle/Form/TimesheetType.php
namespace Homecare'HomecareBundle'Form;
use Symfony'Component'Form'AbstractType;
use Symfony'Component'Form'FormBuilderInterface;
use Symfony'Component'OptionsResolver'OptionsResolverInterface;
 class TimesheetType extends AbstractType
{
/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('agency')
        ->add('recipient')
        ->add('pca')
        ->add('service')
                    ->add('continueTimesheetNumber')
                    ->add('visitRatio')
                    ->add('timeIn')
                    ->add('timeOut')
    ;
            $builder->add('careOption', 'entity', array(
                'class' => 'HomecareHomecareBundle:CareOptions',
                'property' => 'careOption',
                    'expanded' => true,
                    'multiple' => true,
                    'label' => false,
                    'by_reference' => false,
            ));
}
/**
 * @param OptionsResolverInterface $resolver
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Homecare'HomecareBundle'Entity'Timesheet',
                    'csrf_protection'   => false,
    ));
}
/**
 * @return string
 */
public function getName()
{
    return 'homecare_homecarebundle_timesheet';
}
}

以下是ApiControllers:

<?php
//src/Homecare/HomecareApiBundle/Controller/TimesheetApiController.php
namespace Homecare'HomecareApiBundle'Controller;
use Symfony'Bundle'FrameworkBundle'Controller'Controller;
use FOS'RestBundle'Controller'Annotations'View;
use Symfony'Component'HttpFoundation'Response;
use Symfony'Component'HttpFoundation'Request;
use Homecare'HomecareBundle'Entity'Timesheet;
use Homecare'HomecareBundle'Entity'Services;
use Homecare'HomecareBundle'Entity'CareOptions;
use Homecare'HomecareBundle'Form'TimesheetType;
use Sensio'Bundle'FrameworkExtraBundle'Configuration'ParamConverter;
use JMS'Serializer'SerializerBuilder;
use FOS'RestBundle'View'View as V;
use Doctrine'Common'Collections'ArrayCollection;

class TimesheetApiController extends Controller
{


/**
* @View()
*/
public function patchCareoptionAction( Timesheet $timesheet )
{
    return $this->updateTimesheetForm( $timesheet );
    }




/**
* @View()
*/
public function postCreateTimesheetAction( Request $request )
{
        return $this->createTimesheetForm( $request, new Timesheet() );
    }




    /**
    * @View()
    */
    public function patchTimesheetAction( Timesheet $timesheet )
    {
        return $this->updateTimesheetForm( $timesheet );
        }



        private function setMethod( $statusCode, $timesheet = null ){
           switch( $statusCode ) {
                case 201:
                return array( 'method' => 'POST' );
                break;
                case 204:
                return array( 
                    'action' => $this->generateUrl('patch_timesheet', array('timesheet' => $timesheet->getId())),
                    'method' => 'PATCH' 
                );
                break;
            }
        }



            /**
            * @View()
            */
            private function updateTimesheetForm( Timesheet $timesheet)
                {

                    $statusCode = 204;
                    $form = $this->createForm(new TimesheetType(), $timesheet, $this->setMethod( $statusCode, $timesheet ) );

                         $form->handleRequest( $this->getRequest() );

                    if ($form->isValid()) {

                                $em = $this->getDoctrine()->getManager();

                                //$careOption = $em->getRepository( "HomecareHomecareBundle:CareOptions" )->findOneById(456);

                                //$timesheet->addCareOption( $careOption );
                                $em->persist( $timesheet );
                    $em->flush();
                        $response = new Response();
                        $response->setStatusCode( $statusCode );

                        return $response;
                    }
                    return V::create($form, 400);
                }




                    /**
                    * @View()
                    */
                  private function createTimesheetForm( $request, Timesheet $timesheet )
                     {

                              $statusCode = 201;
                                $form = $this->createForm( new TimesheetType(), $timesheet, $this->setMethod( $statusCode ) );

                         $form->handleRequest( $this->getRequest() );
                         if ( $form->isValid() ) {
                             //$user->save();
                                         //$timesheet = $form->getData();
                             $response = new Response();
                             $response->setStatusCode(201);

                                        $em = $this->getDoctrine()->getManager();
                                        $em->persist( $timesheet );
                            $em->flush();


                       //return V::create($form, 201);
                             //return $response;
                             //return array( $form, array("timesheet" => array("id" => $timesheet->getId() ) ) );

     return V::create( array("createdTimesheet" => array("id" => $timesheet->getId() ) ), $statusCode );

                                        // return array( $form, array("timesheet" => array("id" => $timesheet->getId() ) ) );
                         }
                         return V::create($form, 400);
                     }



}

您需要调用第二个API来删除之前添加的2个选项,或者在您的updateTimesheet中删除之前添加了2个选项。您可以通过在存储库中创建一个函数通过查询来选择它们:

public function getLastTwoCareOptions(){
$query = "SELECT co.id FROM CareOptionTable co INNER JOIN TimesheetTable ts WHERE ts.id = timesheetid ORDER BY co.id LIMIT 2;";
$connection = $this->getEntityManager()->getConnection();
$prep_query = $connection->prepare($req);
$result = $prep_query->fetchAll();
}

如果您可能需要在某一天或更长时间更新3个临终关怀选项,您可以将该限制作为函数的参数。

然后获取id并将其从时间表中删除。另一种解决方案是以不同的方式使用相同的查询来使用SQL查询删除它们,而不必选择然后删除。