连接两个实体的信息的最佳做法是什么?

时间:2012-02-19 08:54:53

标签: dependency-injection symfony

我用语言提问我有点困难,但我会尝试。

我有两个实体。一个叫做Product the other Sale。每个产品都有现场定义该产品的可用商品数量。每个销售都有一个字段,说明一种产品的销售商品数量。销售产品是OneToMany-Relationship。

现在,如果我想知道产品是否售罄,我需要创建一个功能,从产品的初始可用性编号中减去已售商品的总数。类似于function getAvailableQuantity()

我的问题是:我在哪里放置这种方法? 我很想把它放在Product Repository中 - 但由于这个方法需要访问Sales实体,因此这违反了Dependency Injection。但是,将它放在控制器中似乎是一种不必要的绕行,因为我失去了在Twig模板中调用{{ product.getAvailableQuantity }}的可能性。

要走的路是什么?

感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

我建议立即从Product::available_items减去已售商品。这样可以立即解决问题,因为Product::available_items始终会反映可用项目的数量。

方法编号。 1

立即从Sale::quantity减去Product

public function setProduct(ProductInterface $product)
{
    $new_count = $product->getAvailableItems() - $this->getQuantity();
    $product->setAvailableItems($new_count);

    $this->product = $product;
}

您还必须在可能更改可用项目数的所有控制器中进行减法。


方法编号。 2

就个人而言,我实际上更喜欢这种方法而不是第一种方法,因为它将逻辑保存在一个地方,并且通常会导致控制器更短。此外,我的实体通常足够长,没有所有域逻辑。

假设Sale引用了Product,我将逻辑放入服务(特定于实体的实体管理器,例如UserManager。它被称为{{ 1}}在我们的例子中)。其中的方法看起来类似于:

SaleManager

我没有触及如果您要从public function updateSale(SaleInterface $sale, $flush = true) { $product = $sale->getProduct(); $new_count = $product->getAvailableItems() - $sale->getQuantity(); if ($new_count < 0) { throw new NegativeQuantityException(); } $product->setAvailableItems($new_count); $this->em->persist($sale); if (true === $flush) { $this->em->flush(); } } 移除Sale或切换Product会发生什么的问题,但您也必须考虑这一点。

答案 1 :(得分:1)

  

我在哪里放置此方法?

考虑创建一个注入实体管理器的ProductSalesManager服务。从控制器你会有类似的东西:

$productSalesManager = $this->get(product_sales.manager);
$products = $productSalesManager->getProductsWithAvailableQuantity();

现在,您可以将您的逻辑放在管理器中,而不必担心它恰好位于哪个存储库中。它还将您的控制器与Doctrine本身分离。

我不太确定维护产品本身的现有库存是个好主意,但这完全取决于你。

答案 2 :(得分:0)

由于产品的可用数量,我认为工作必须由产品实体完成。

如果您使用Doctrine,它会在您的产品实体中生成函数addSale(名称取决于您如何定义关系)。我应该改变这个功能来进行计算。 假设您的商品实体中的字段名为available_quantity,并且销售实体中的字段名为items_number

public function addSale ( $sale )
{
    $this->setAvailableQuantity($this->getAvailableQuantity() - $sale->getItemsNumber());
    $this->sales[] = $sale;
}

然后在您的控制器中将销售额添加到产品中:

// get the product
$product = $this->getDoctrine()
    ->getRepository('AcmeStoreBundle:Product')
    ->find($id);
// build your Sale object
$sale = new Sale();
...
// add it to the product
$product->addSale($sale);

// save all
$em = $this->getDoctrine()->getEntityManager();
$em->persist($sale);
$em->persist($product);
$em->flush();

在您的模板中,您可以获得产品的可用数量:

{{ product.availableQuantity }}