Question

Say I have a system with Products that can have various decoration (or printing) options.

Most products will have a similar range of printing options names, but some maybe unique for a single product.

For example, I could have a cap that could have three different decoration options:

  1. Unbranded
  2. One Color Print
  3. Embroidery

My goal is trying to minimize decoration option names created by admin users so they are always the same. I.E. I don't want some decoration options being called "1 Color Print" and then another one called "One Color Print".

So my plan is in the UI is to have a drop down of existing decoration options names but also give them the option to add a new one (for the edge cases).

However, each decoration option has various other data with it, like setup cost, production time, etc which varies depending on the product.

For example, Hat1 and Hat2 could both have an embroidery decoration option, but Hat1's setup cost is $49 and Hat2's setup cost is only $35.

So my questions is, what is the best way to structure my entities? Should I have three entities: Product, DecorationOption and DecorationOptionName? Or just two entities: Product and DecorationOption?

Please see my code examples for further understand:

  1. Three entities option
  2. Two entities option
Was it helpful?

Solution

I would use the three entity approach, with some minor differences in semantics: Product, Decoration, and ProductDecoration. It's essentially the idea behind a many-to-many join table, but you treat the join as it's own object, where you can store extra information.

Products and Decoration are their own separate entities, and information about the relationship between any given Product and any given DecorationOption is managed in ProductDecoration. You can achieve this using two OneToMany relationships.

<?php

class Product 
{   
    /** @OneToMany(targetEntity="ProductDecoration", mappedBy="product") */
    private $productDecorations;

}


class Decoration
{   
   /** @Column(type="string") */
   private $name;   

   /** @OneToMany(targetEntity="ProductDecoration", mappedBy="decoration") */
   private $productDecorations;
}

class ProductDecorations
{   

   /** @ManyToOne(targetEntity="Product", inversedBy="productDecorations") */
   private $product;

   /** @ManyToOne(targetEntity="Decoration", inversedBy="productDecorations") */
   private $decoration;

   /** @Column(type="integer") */
   private $setupCost;

   /** @Column(type="integer") */
   private $productionTime
}

The only way I'd recommend using the two Entity approach is if you can anticipate never needing more than the 'name' column for the Decoration entity, and you're not bothered by potential database normalization issues.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top