Symfony 教条主义者不为自己的实体工作
我有Symfony 教条主义者不为自己的实体工作,symfony,orm,doctrine-orm,Symfony,Orm,Doctrine Orm,我有客户,产品,预算和预算项目实体预算与@ORM\manytone与客户相关,与@ORM\OneToMany与预算项相关预算项与产品和预算关联为@ORM\manytone 在BudgetItem中,有一种方法可用于计算先前选择的产品的总价格,然后将其保存到预算项目表中。更新项目时,将执行代码并再次成功地将其保存到数据库中。方法如下: public function calculateTotalPrice() { return $this->getProduct()->getP
客户
,产品
,预算
和预算项目
实体<代码>预算与@ORM\manytone与客户
相关,与@ORM\OneToMany与预算项
相关<代码>预算项与产品
和预算
关联为@ORM\manytone
在BudgetItem
中,有一种方法可用于计算先前选择的产品的总价格,然后将其保存到预算项目
表中。更新项目时,将执行代码并再次成功地将其保存到数据库中。方法如下:
public function calculateTotalPrice()
{
return $this->getProduct()->getPrice() * $this->getMeters();
}
/**
* @ORM\PrePersist
*/
public function onPreEvents()
{
$this->setPrice($this->calculateTotalPrice());
}
现在,我有了预算
:
/**
* @return \DateTime
*/
public function generateNextPaymentDate()
{
if ($this->getStartsAt() !== null) {
$date = new \DateTime($this->getStartsAt()->format('Y-m-d'));
return $date->add(new \DateInterval('P' . $this->getCheckFor() . 'D'));
}
}
/**
* @return decimal
*/
public function calculateTotalBudgetPrice()
{
$totalBudgetPrice = 0;
foreach ($this->getItems() as $item) {
$totalBudgetPrice += $item->getPrice();
}
return $totalBudgetPrice;
}
/**
* @return decimal
*/
public function calculateInstallmentRatePrice()
{
return $this->calculateTotalBudgetPrice() / $this->getInstallmentRate();
}
/**
* @ORM\PrePersist
*/
public function onPreEvents()
{
$this->setNextPaymentDate($this->generateNextPaymentDate());
$this->setInstallmentRatePrice($this->calculateInstallmentRatePrice());
$this->setTotalBudgetPrice($this->calculateTotalBudgetPrice());
}
在编辑预算后,所有这些方法的结果都不会保留到数据库中。如果我理解得很好,Doctrine2似乎不会更新其他相关实体,但这些字段属于该实体。我还需要做什么
编辑
BudgetController
,我在其中持久化并刷新
<?php
namespace CDGBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use CDGBundle\Entity\Budget;
use CDGBundle\Form\BudgetType;
class BudgetController extends Controller
{
/**
* Lista todos os orçamentos
*/
public function indexAction()
{
return $this->render('budget/index.html.twig', array(
'budgets' => $this->getDoctrine()->getRepository('CDGBundle:Budget')->findAll(),
'title' => 'Lista de Orçamentos'
));
}
/**
* Adicionar um novo orçamento
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function addAction(Request $request)
{
$budget = new Budget();
$form = $this->createForm(new BudgetType(), $budget);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
return $this->render('budget/add.html.twig', array(
'form' => $form->createView(),
'title' => 'Novo Orçamento'
));
}
/**
* Exibe os detalhes do orçamento selecionado
*
* @param integer $id
* @return Budget
*/
public function showAction($id)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
return $this->render('budget/show.html.twig', array(
'budget' => $budget,
'title' => 'Dados do orçamento #' . $budget->getId()
));
}
/**
* Edita as informações do orçamento selecionado
*
* @param integer $id
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function editAction($id, Request $request)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
$form = $this->createForm(new BudgetType(), $budget);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
return $this->render('budget/edit.html.twig', array(
'form' => $form->createView(),
'title' => 'Editar orçamento #' . $budget->getId()
));
}
/**
* Deleção de um orçamento
*
* @param integer $id
* @return Budget
*/
public function deleteAction($id)
{
$budget = $this->getDoctrine()->getRepository('CDGBundle:Budget')->find($id);
$em = $this->getDoctrine()->getManager();
$em->remove($budget);
$em->flush();
return $this->redirectToRoute('budgets');
}
}
EDIT2
我刚刚意识到@ORM\PreUpdate正在运行,但仅适用于我的nextPaymentDate
。我在预算
中有一个集合
,在产品控制器
中有一种收集产品信息的方法:
<?php
namespace CDGBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use CDGBundle\Entity\Product;
use CDGBundle\Form\ProductType;
use Symfony\Component\HttpFoundation\JsonResponse;
class ProductController extends Controller
{
/**
* Lista todos os materials
*/
public function indexAction()
{
return $this->render('product/index.html.twig', array(
'products' => $this->getDoctrine()->getRepository('CDGBundle:Product')->findAll(),
'title' => 'Lista de Materiais'
));
}
/**
* Adicionar um novo material
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function addAction(Request $request)
{
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/add.html.twig', array(
'form' => $form->createView(),
'title' => 'Novo Material'
));
}
/**
* Exibe os detalhes do material selecionado
*
* @param integer $id
* @return Product
*/
public function showAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
return $this->render('product/show.html.twig', array(
'product' => $product,
'title' => 'Dados do material #' . $product->getId()
));
}
/**
* Edita as informações do material selecionado
*
* @param integer $id
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function editAction($id, Request $request)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->merge($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/edit.html.twig', array(
'form' => $form->createView(),
'title' => 'Editar material #' . $product->getId() . ' - ' . $product->getName()
));
}
/**
* Deleção de um material
*
* @param integer $id
* @return Product
*/
public function deleteAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$em = $this->getDoctrine()->getManager();
$em->remove($product);
$em->flush();
return $this->redirectToRoute('products');
}
/**
* Traz as informações do material selecionado na criação do orçamento.
*
* @param Request $request
* @return JsonResponse
*/
public function getProductInfoAction(Request $request)
{
$id = $request->query->get('id');
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
if ($request->query->get('format') == 'json') {
$data = array(
'id' => $product->getId(),
'name' => $product->getName(),
'price' => $product->getPrice(),
'meters' => $product->getMeters(),
'description' => $product->getDescription(),
'created_at' => $product->getCreatedAt()->format('d-m-Y H:i'),
);
return new JsonResponse($data, 200, array(
'Content-type' => 'application/json'
));
}
}
}
请参见,特别是预科生
应注意,此事件仅在初始启动时触发
实体的持久化(即,它不会在将来的更新中触发)
因此,您还需要添加一个预更新侦听器。请参阅,特别是预更新侦听器
应注意,此事件仅在初始启动时触发
实体的持久化(即,它不会在将来的更新中触发)
因此,您还需要添加一个预更新侦听器。我刚刚看到了它。更新后执行calculateTotalPrice
方法,因为它实际上是一个设置总值的JavaScript函数。这种方法实际上是无用的。但是,添加预更新仍然不起作用。我在PrePersist下面添加了注释,或者我需要创建另一个方法?您的实体上是否设置了@ORM\HasLifecycleCallbacks?您可以在单个方法上同时设置更新/持久化,这样就不会有问题了。是的,我会这样做,因为我创建了它。我看不出您所做的有任何错误。我甚至在本地测试了一个类似的类型方法,它可以在实体的创建和更新上工作。请你看看我在Github中的项目,看看我是否做错了什么?我刚看到。更新后执行calculateTotalPrice
方法,因为它实际上是一个设置总值的JavaScript函数。这种方法实际上是无用的。但是,添加预更新仍然不起作用。我在PrePersist下面添加了注释,或者我需要创建另一个方法?您的实体上是否设置了@ORM\HasLifecycleCallbacks?您可以在单个方法上同时设置更新/持久化,这样就不会有问题了。是的,我会这样做,因为我创建了它。我看不出您所做的有任何错误。我甚至在本地测试了一个类似的类型方法,它可以在实体的创建和更新上工作。请你看看我在Github中的项目,看看我是否做错了什么?
<?php
namespace CDGBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use CDGBundle\Entity\Product;
use CDGBundle\Form\ProductType;
use Symfony\Component\HttpFoundation\JsonResponse;
class ProductController extends Controller
{
/**
* Lista todos os materials
*/
public function indexAction()
{
return $this->render('product/index.html.twig', array(
'products' => $this->getDoctrine()->getRepository('CDGBundle:Product')->findAll(),
'title' => 'Lista de Materiais'
));
}
/**
* Adicionar um novo material
*
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function addAction(Request $request)
{
$product = new Product();
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/add.html.twig', array(
'form' => $form->createView(),
'title' => 'Novo Material'
));
}
/**
* Exibe os detalhes do material selecionado
*
* @param integer $id
* @return Product
*/
public function showAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
return $this->render('product/show.html.twig', array(
'product' => $product,
'title' => 'Dados do material #' . $product->getId()
));
}
/**
* Edita as informações do material selecionado
*
* @param integer $id
* @param Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|Response
*/
public function editAction($id, Request $request)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$form = $this->createForm(new ProductType(), $product);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->merge($product);
$em->flush();
return $this->redirectToRoute('products');
}
return $this->render('product/edit.html.twig', array(
'form' => $form->createView(),
'title' => 'Editar material #' . $product->getId() . ' - ' . $product->getName()
));
}
/**
* Deleção de um material
*
* @param integer $id
* @return Product
*/
public function deleteAction($id)
{
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
$em = $this->getDoctrine()->getManager();
$em->remove($product);
$em->flush();
return $this->redirectToRoute('products');
}
/**
* Traz as informações do material selecionado na criação do orçamento.
*
* @param Request $request
* @return JsonResponse
*/
public function getProductInfoAction(Request $request)
{
$id = $request->query->get('id');
$product = $this->getDoctrine()->getRepository('CDGBundle:Product')->find($id);
if ($request->query->get('format') == 'json') {
$data = array(
'id' => $product->getId(),
'name' => $product->getName(),
'price' => $product->getPrice(),
'meters' => $product->getMeters(),
'description' => $product->getDescription(),
'created_at' => $product->getCreatedAt()->format('d-m-Y H:i'),
);
return new JsonResponse($data, 200, array(
'Content-type' => 'application/json'
));
}
}
}