我正在编写一些简单的脚本,但无法解决这个问题。
/**
* Booking
* @ORM'Table()
* @ORM'Entity(repositoryClass="Tons'BookingBundle'Entity'BookingRepository")
* @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
* @Assert'Callback(methods={"isSinceLessThanTill"}, groups={"search","default"})
*/
class Booking
和repository Method
/**
* Get room state for a certain time period
*
* @param array $criteria
* @return array
*/
public function getInterferingRoomBookings(array $criteria)
{
/** @var $room Room */
$room = $criteria['room'];
$builder = $this->getQueryForRoomsBooked($criteria);
$builder->andWhere("ira.room = :room")->setParameter("room", $room);
return $builder->getQuery()->getArrayResult();
}
问题是,这工作在创建方法像它应该,但是当更新现有实体时,它违反了这个约束。
我试图添加Id约束,但在创建实体时,Id为空,因此存储库方法甚至不启动。此外,我试图删除实体,然后重新创建它。像
$em->remove($entity);
$em->flush();
//-----------
$em->persist($entity);
$em->flush();
,但这也不起作用
创建行动
/**
* Creates a new Booking entity.
*
* @Route("/create", name="booking_create")
* @Method("POST")
* @Template("TonsBookingBundle:Booking:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Booking();
$form = $this->createForm(new BookingType(), $entity);
$form->bind($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$room = $entity->getRoom();
if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId())
{
$entity->setCreatedAt(new 'DateTime());
$entity->setUpdatedAt(new 'DateTime());
$entity->setManager($this->getUser());
$em->persist($entity);
$room->setLocked(false);
$room->setLockedBy(null);
$room->setLockedAt(null);
$em->persist($room);
$em->flush();
return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId())));
}
else
{
$form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером"));
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
Update操作
/**
* Edits an existing Booking entity.
*
* @Route("/edit/{id}/save", name="booking_update")
* @Method("PUT")
* @Template("TonsBookingBundle:Booking:edit.html.twig")
*/
public function updateAction(Request $request, $id)
{
/** @var $em EntityManager */
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TonsBookingBundle:Booking')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Booking entity.');
}
$editForm = $this->createForm(new BookingType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('booking_edit', array('id' => $id)));
}
return array(
'entity' => $entity,
'form' => $editForm->createView(),
);
}
我知道了!我把注释改成了
/**
* Booking
* @ORM'Table()
* @ORM'Entity(repositoryClass="Tons'BookingBundle'Entity'BookingRepository")
* @UniqueEntity(fields={"id","room", "since", "till"}, repositoryMethod="getInterferingRoomBookings")
* @UniqueEntity(fields={"room", "since", "till"}, repositoryMethod="getInterferingRoomBookings",groups={"create"})
* @Assert'Callback(methods={"isSinceLessThanTill"}, groups={"search","default"})
*/
class Booking
复制BookingType到BookingTypeCreate并添加
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Tons'BookingBundle'Entity'Booking',
'validation_groups' => array('create'),
));
}
形成默认值。因此,当将实体传递给验证方法时,参数是不同的。我认为这仍然是一个变通方法
简短的回答:您没有将表单数据输入到实体中,因此您正在处理一个不知道其房间已在表单中设置的新实体。
长篇大论:获取表单数据并将其放入实体中允许您在更新之前操作数据。请参见修改后的控制器。关键行
$entity = form->getData();
然后允许$room=$entity->getRoom();
/**
* Creates a new Booking entity.
*
* @Route("/create", name="booking_create")
* @Method("POST")
* @Template("TonsBookingBundle:Booking:new.html.twig")
*/
public function createAction(Request $request)
{
$entity = new Booking();
$form = $this->createForm(new BookingType(), $entity);
$form->bind($request);
$entity = $form->getData(); // Lighthart's addition
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$room = $entity->getRoom();
if($room->getLocked() && $room->getLockedBy()->getId() === $this->getUser()->getId())
{
$entity->setCreatedAt(new 'DateTime());
$entity->setUpdatedAt(new 'DateTime());
$entity->setManager($this->getUser());
$em->persist($entity);
$room->setLocked(false);
$room->setLockedBy(null);
$room->setLockedAt(null);
$em->persist($room);
$em->flush();
return $this->redirect($this->generateUrl('booking_show', array('id' => $entity->getId())));
}
else
{
$form->addError(new FormError("Номер в текущий момент не заблокирован или заблокирован другим менеджером"));
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
传递一个额外的标识符(可能是token
)到唯一的检查字段(例如loginName
) (fields={"token", "loginName"}
),到repositoryMethod。id
本身不工作,它在对象创建时为null,并且没有执行repositoryMethod。我在构造函数方法中创建token
。在创建或更新操作时需要令牌来标识实体。
/**
* @ORM'Table(name="anbieterregistrierung")
* @ORM'Entity(repositoryClass="AnbieterRegistrierungRepository")
* @UniqueEntity(
* fields={"token", "loginName"},
* repositoryMethod="findUniqueEntity"
* )
*/
然后在存储库类中编辑WHERE DQL:
public function findUniqueEntity(array $parameter)
{
$loginName = $parameter['loginName'];
$token = $parameter['token'];
.
.
.
. . . WHERE anbieterregistrierung.loginName = :loginName AND anbieterregistrierung.token <> :token
.
.
.
}