Reputation: 1890
Ok so I currently have set up a one-to-many-to-one relation over 3 tables:
Recipes-ProductRecipe-Products
###Recipes.yml###
oneToMany:
products:
targetEntity: ProductRecipe
mappedBy: recipes
cascade: ["all"]
###ProductRecipe.yml###
manyToOne:
products:
targetEntity: Products
inversedBy: recipes
recipes:
targetEntity: Recipes
inversedBy: products
###Products.yml###
oneToMany:
recipes:
targetEntity: ProductRecipe
mappedBy: products
cascade: ["all"]
I have set up these entities using the built in command (doctrine:generate:entities) so I have all my setter/getters/_construct/_tostring in place.
Now I have all this set up (which works fine on it's own) I want the user to be able to add new products to a recipe from the recipe form. So I have made a collection of forms in the recipe form.
class RecipesType extends AbstractType{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('recipename')
->add('recipedesc')
->add('recipeyeild')
->add('recipecost');
$builder->add('products', 'collection', array(
'type' => new ProductRecipeType(),
'allow_add' => true,));
}
Which connects to this form:
class ProductRecipeType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('ammount')
->add('products')
;
}
And in my Recipes Controller I have this:
public function newAction()
{
$entity = new Recipes();
$pr = new ProductRecipe();
$entity->getProducts()->add($pr);
$form = $this->createCreateForm($entity);
So far so good, the forms are created fine and persist to the database fine. However in my Many table the Recipe_ID field is not been filled with the recipe being created at that time. How do I fill that field on persist? Otherwise a user is creating a recipe and adding products to the recipe, but then when persisted I just have a new recipe with no products and a collection of product ammounts not connected to a recipe.
Sorry if I've written this up in a confusing way... It's because I'm confused myself.
Just to help a little I'm adding my controllers code trimmed down a little:
class Recipes
{
private $id;
private $recipename;
private $recipedesc;
private $recipeyeild;
private $recipecost;
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
{
return $this->id;
}
public function addProduct(\BC\InventoryBundle\Entity\ProductRecipe $pr)//<-this was $products
{
//$this->products[] = $products; <-Original code now changed to below as suggested.
$this->products->add($pr);
$pr->setRecipes($this);
return $this;
}
public function removeProduct(\BC\InventoryBundle\Entity\ProductRecipe $products)
{
$this->products->removeElement($products);
}
public function getProducts()
{
return $this->products;
}
And my ProductRecipe entity:
class ProductRecipe
{
private $id;
private $ammount;
private $products;
private $recipes;
public function getId()
{
return $this->id;
}
public function setAmmount($ammount)
{
$this->ammount = $ammount;
return $this;
}
public function getAmmount()
{
return $this->ammount;
}
public function setProducts(\BC\InventoryBundle\Entity\Products $products = null)
{
$this->products = $products;
return $this;
}
public function getProducts()
{
return $this->products;
}
public function setRecipes(\BC\InventoryBundle\Entity\Recipes $recipes = null)
{
$this->recipes = $recipes;
return $this;
}
public function getRecipes()
{
return $this->recipes;
}
So after Cerad's suggestion I've got these...
//Recipes entity
public function addProduct(\BC\InventoryBundle\Entity\ProductRecipe $products)
{
$this->products->add($products);
$products->setRecipes($this);
return $this;
}
//Recipes Controller
public function newAction()
{
$entity = new Recipes();
$products = new ProductRecipe();
$entity->getProducts()->add($products);
$entity->addProduct($products);
$form = $this->createCreateForm($entity);
return $this->render('BCInventoryBundle:Recipes:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
Still to no avail...
This Now works my issue was the majority of what I had in newAction should have been in the createAction. Works perfectly. Thank you Cerad.
Upvotes: 0
Views: 216
Reputation: 48893
This is a common problem. You are never calling the ProductRecipe::setRecipe() method. Probably not calling setProduct either.
class Recipe
{
public function addProduct($pr)
{
$this->products->add($pr);
$pr->setRecipe($this); // *** This is what you need to add
In your controller:
$entity->addProduct($pr);
And while not directly relevant, consider changing Products and Recipes to Product and Recipe.
Upvotes: 1