У меня, похоже, проблема. И я уверен, что это действительно простое решение. У меня есть API, который использует пакет FOS Rest. У меня есть вызов, который отправляет запрос POST для postCreateTimesheetAction (Request $ request), который создает пустую строку в таблице расписаний. У меня есть еще один call patchTimesheetAction, который laters добавляет некоторые данные в таблицу. Хорошо, все хорошо. У меня есть еще один метод patchCareoptionAction (Timesheet $ timesheet), который создает строку в таблице, которая имеет много-много отношений, построенных из CareOptions.php (ниже) и Timesheet.php (ниже). Все вызовы api работают хорошо и работают так, как должны. Я буду размещать их ниже здесь:Symfony FOS Rest Bundle Api Call Many to Many Отношения
создает новую пустую строку в расписании таблицы расписания: (Timesheet.php)
локон -H "Accept: приложения/JSON" -H «Content-тип:/json "-i -X POST -d '{" homecare_homecarebundle_timesheet ":" "}' www.hc-timesheets-demo.com/app_dev.php/api/v1/create/timesheet
обновляет строку расписания с данными :
curl -i -H "Accept: application/json" -H "Content-type: application/json" -d '{"homecare_homecarebundle_timesheet": {"agency": "157", "recipient": " 154 "," pca ":" 16 "," service ":" 6 "}} '-XP ATCH www.hc-timesheets-demo.com/app_dev.php/api/v1/timesheet/31
и, наконец, создает многие ко многим:
локон -i -H «Accept: приложение/JSon "-H" Content-type: application/json "-d '{" homecare_homecarebundle_timesheet ": {" careOption ": [456,457]}}' -X PATCH www.hc-timesheets-demo.com/app_dev.php/api/ v1/careoption/31
обратите внимание на 31 в конце запроса на исправление. Это идентификатор расписания, созданного в таблице с первого вызова api. Так что давайте перейдем к моему вопросу! Всякий раз, когда я вызываю третий вызов 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 TimesheetType.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);
}
}