Не удается сохранить коллекцию Symfony с двойной вложенной формой

Я получаю следующую ошибку при попытке отправить свою форму:

Возникла исключительная ситуация при выполнении ‘INSERT INTO UserIngredientSupplier (количество, стоимость, созданный, обновленный, единичный,
OrganizationId, userIngredientId) ЗНАЧЕНИЯ (?,?,?,?,?,?,?) ‘с
params [1000, 4.5, «2014-11-27 22:46:51», «2014-11-27 22:46:51», 4, 2,
ноль]:

SQLSTATE [23000]: Нарушение ограничения целостности: 1048 Le champ ‘userIngredientId’ ne peut être vide (null)

Я не забыла поставить 'by_reference' => falseЯ не забыла cascad={"persist"} на моих сущностях, и я также установил сеттеры для моих сущностей User и UserIngredients, таких как:

Параметры моего поста следующие:

[
userIngredients => [
0 => [
nickname => Blé,
name => Ebly® - 500 g,
quantityInStock => 5000,
unit => 4,
userIngredientSuppliers => [
0 => [
quantity => 1000,
cost => 4.5,
unit => 4,
userSupplier => 2
]
]
],
1 => [
nickname => Lait,
name => Lait Viva,
quantityInStock => 4000,
unit => 4
]
],
submit => ,
_token => PRktvw2sSa7lBiZ9DIIAzhzaxg4ysWGyAazbZHPOnMA
]

Чего мне не хватает? Что бы UserIngredientId не быть упорным? Разве это не идет с UserIngredientSupplierType вызывается из UserIngredientType ?

контроллер:

    /**
* Displays a form to create a new FoodAnalyticsUserIngredient entity.
*
* @Route("/ing1", name="ing1")
* @Method({"PUT","GET"})
* @Template(":FoodAnalytics/UserIngredient:ing1.html.twig")
* @param Request $request
* @return array|SymfonyComponentHttpFoundationRedirectResponse
*/
public function parameterIng1Action(Request $request)
{
$userIngredientManager = $this->get('user_ingredient_manager');
$ingredient = $this->getDoctrine()->getRepository('AppBundle:FoodAnalyticsUserIngredient')->findOneById(5);
$parameterUserIngredientsForm = $userIngredientManager->getParameterIng1Form($ingredient);if ($request->getMethod()=='PUT')
{
$formManager = $this->get('form_manager');

if ($formManager->handleRequestAndFlush($parameterUserIngredientsForm,$ingredient))
{
return $this->redirect($this->generateUrl('my_ingredients').'/parameter_selection');
}
}

return array(
'parameter_user_ingredients_form' => $parameterUserIngredientsForm->createView()
);
}/**
* @return SymfonyComponentFormForm|SymfonyComponentFormFormInterface
*/
public function getParameterIng1Form($ingredient)
{
$unitRepository = $this->em->getRepository('AppBundle:FoodAnalyticsUnit');

$userIngredientsForm = $this->formManager->createForm(
new UserIngredientType($unitRepository),
$ingredient,
'PUT',
'ing1',
null,
'Enregistrer les changements'
);

return $userIngredientsForm;
}

Тип формы:

<?php
namespace AppBundleFormFoodAnalytics;

use AppBundleFormEventListenerAddUnitFieldSubscriber;
use AppBundleRepositoryFoodAnalyticsUnitRepository;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;

class UserIngredientType extends AbstractType
{

protected $unitRepository;

public function __construct(UnitRepository $unitRepository)
{
$this->unitRepository = $unitRepository;
}

/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nickname', null, array(
'label'=>'Nom raccourci',
'attr'=>array(
'data-toggle'=>"tooltip",
'data-placement'=>"top",
'title'=>"Le nom raccourci peut être utilisé dans les recettes. Il doit être unique",
'class' => 'input-sm'
)))
->add('name', null, array(
'label'=>'Nom complet',
'attr'=>array(
'data-toggle'=>"tooltip",
'data-placement'=>"top",
'title'=>"Le nom complet peut être utilisé dans les recettes. Il doit être unique.",
'class' => 'input-sm'
)))
->add('quantityInStock', null, array(
'label'=>'Stock',
'attr'=>array(
'data-toggle'=>"tooltip",
'data-placement'=>"top",
'title'=>"Indiquez l'état de votre stock pour gérer vos commandes",
'class' => 'input-sm'
)))
->add('userIngredientSuppliers', 'collection', array(
'type' => new UserIngredientSupplierType($this->unitRepository),
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
;

$builder->addEventSubscriber(new AddUnitFieldSubscriber($this->unitRepository));
}

/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundleEntityFoodAnalyticsUserIngredient'
));
}

/**
* @return string
*/
public function getName()
{
return 'appbundle_foodanalytics_user_ingredient';
}
}

Сущность:

<?php
namespace AppBundleEntityFoodAnalytics;
use AppBundleModelBaseCategoryClass;
use DoctrineCommonCollectionsArrayCollection;
use DoctrineORMMapping AS ORM;
use GedmoMappingAnnotation as Gedmo;

/**
* @ORMEntity(repositoryClass="AppBundleRepositoryFoodAnalyticsUserIngredientRepository")
* @GedmoTree(type="nested")
*/
class UserIngredient extends BaseCategoryClass
{
/**
* @ORMId
* @ORMColumn(type="integer", length=11)
* @ORMGeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORMColumn(type="boolean", nullable=true)
*/
private $isImported;

/**
* @ORMColumn(type="string", length=100, nullable=false)
*/
protected $name;

/**
* @ORMColumn(type="string", length=50, nullable=true)
*/
private $nickname;

/**
* @ORMColumn(type="decimal", precision=10, scale=2, nullable=true)
*/
private $quantityInStock;

/**
* @ORMManyToOne(targetEntity="AppBundleEntityMarketPlaceProduct", inversedBy="userIngredients")
* @ORMJoinColumn(name="productId", referencedColumnName="id", nullable=false, onDelete="cascade")
*/
private $product;

/**
* @GedmoBlameable(on="create")
* @ORMManyToOne(targetEntity="AppBundleEntityUserUser", inversedBy="userIngredients")
* @ORMJoinColumn(name="userId", referencedColumnName="id", nullable=false, onDelete="cascade")
*/
private $user;

/**
* @ORMManyToOne(targetEntity="AppBundleEntityFoodAnalyticsUnit")
* @ORMJoinColumn(name="unitId", referencedColumnName="id", nullable=false, onDelete="restrict")
*/
private $unit;

/**
* @ORMOneToMany(targetEntity="AppBundleEntityFoodAnalyticsUserRecipeIngredient", mappedBy="userIngredient")
*/
protected $userRecipeIngredients;

/**
* @ORMOneToMany(targetEntity="AppBundleEntityFoodAnalyticsUserIngredientSupplier", mappedBy="userIngredient", cascade={"persist"})
*/
protected $userIngredientSuppliers;

/**
* @GedmoTreeParent
* @ORMManyToOne(targetEntity="AppBundleEntityFoodAnalyticsUserIngredient", inversedBy="children")
* @ORMJoinColumn(name="parent_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $parent;

/**
* @ORMOneToMany(targetEntity="AppBundleEntityFoodAnalyticsUserIngredient", mappedBy="parent", cascade={"persist"})
*/
protected $children;public function __toString()
{
return $this->name;
}/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set name
*
* @param string $name
*
* @return UserIngredient
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* Set nickname
*
* @param string $nickname
*
* @return UserIngredient
*/
public function setNickname($nickname)
{
$this->nickname = $nickname;

return $this;
}

/**
* Get nickname
*
* @return string
*/
public function getNickname()
{
return $this->nickname;
}

/**
* Set quantityInStock
*
* @param float $quantityInStock
*
* @return UserIngredient
*/
public function setQuantityInStock($quantityInStock)
{
$this->quantityInStock = $quantityInStock;

return $this;
}

/**
* Get quantityInStock
*
* @return string
*/
public function getQuantityInStock()
{
return $this->quantityInStock;
}

/**
* Set product
*
* @param AppBundleEntityMarketPlaceProduct $product
*
* @return UserIngredient
*/
public function setProduct(AppBundleEntityMarketPlaceProduct $product)
{
$this->product = $product;

return $this;
}

/**
* Get product
*
* @return AppBundleEntityMarketPlaceProduct
*/
public function getProduct()
{
return $this->product;
}

/**
* Set user
*
* @param AppBundleEntityUserUser $user
*
* @return UserIngredient
*/
public function setUser(AppBundleEntityUserUser $user)
{
$this->user = $user;

return $this;
}

/**
* Get user
*
* @return AppBundleEntityUserUser
*/
public function getUser()
{
return $this->user;
}

/**
* Set unit
*
* @param AppBundleEntityFoodAnalyticsUnit $unit
*
* @return UserIngredient
*/
public function setUnit(AppBundleEntityFoodAnalyticsUnit $unit)
{
$this->unit = $unit;

return $this;
}

/**
* Get unit
*
* @return AppBundleEntityFoodAnalyticsUnit
*/
public function getUnit()
{
return $this->unit;
}

/**
* Set isImported
*
* @param boolean $isImported
*
* @return UserIngredient
*/
public function setIsImported($isImported)
{
$this->isImported = $isImported;

return $this;
}

/**
* Get isImported
*
* @return boolean
*/
public function getIsImported()
{
return $this->isImported;
}

/**
* Constructor
*/
public function __construct()
{
$this->userRecipeIngredients = new DoctrineCommonCollectionsArrayCollection();
}

/**
* Add userRecipeIngredient
*
* @param AppBundleEntityFoodAnalyticsUserRecipeIngredient $userRecipeIngredient
*
* @return UserIngredient
*/
public function addUserRecipeIngredient(AppBundleEntityFoodAnalyticsUserRecipeIngredient $userRecipeIngredient)
{
$this->userRecipeIngredients[] = $userRecipeIngredient;

return $this;
}

/**
* Remove userRecipeIngredient
*
* @param AppBundleEntityFoodAnalyticsUserRecipeIngredient $userRecipeIngredient
*/
public function removeUserRecipeIngredient(AppBundleEntityFoodAnalyticsUserRecipeIngredient $userRecipeIngredient)
{
$this->userRecipeIngredients->removeElement($userRecipeIngredient);
}

/**
* Get userRecipeIngredients
*
* @return DoctrineCommonCollectionsCollection
*/
public function getUserRecipeIngredients()
{
return $this->userRecipeIngredients;
}

/**
* Add userIngredientSupplier
*
* @param AppBundleEntityFoodAnalyticsUserIngredientSupplier $userIngredientSupplier
*
* @return UserIngredient
*/
public function addUserIngredientSupplier(AppBundleEntityFoodAnalyticsUserIngredientSupplier $userIngredientSupplier)
{
//Needed cause the setter wouldn't be called even with by_reference = false
//        $userIngredientSupplier->setUserIngredient($this);

$this->userIngredientSuppliers[] = $userIngredientSupplier;

return $this;
}

/**
* Remove userIngredientSupplier
*
* @param AppBundleEntityFoodAnalyticsUserIngredientSupplier $userIngredientSupplier
*/
public function removeUserIngredientSupplier(AppBundleEntityFoodAnalyticsUserIngredientSupplier $userIngredientSupplier)
{
$this->userIngredientSuppliers->removeElement($userIngredientSupplier);
}

/**
* Get userIngredientSuppliers
*
* @return DoctrineCommonCollectionsCollection
*/
public function getUserIngredientSuppliers()
{
return $this->userIngredientSuppliers;
}

/**
* Set userIngredientSuppliers
*
* @param ArrayCollection $userIngredientSuppliers
* @return DoctrineCommonCollectionsCollection
*/
public function setUserIngredientSuppliers(ArrayCollection $userIngredientSuppliers)
{
/** @var $userIngredientSupplier UserIngredientSupplier */
foreach ($userIngredientSuppliers as $userIngredientSupplier)
{
$userIngredientSupplier->setUserIngredient($this);
}

exit(var_dump($userIngredientSuppliers));

$this->userIngredientSuppliers=$userIngredientSuppliers;
}
}

PHP:

<?php
namespace AppBundleEntityFoodAnalytics;
use DoctrineORMMapping AS ORM;
use GedmoMappingAnnotation as Gedmo;
use GedmoTimestampableTraitsTimestampableEntity;

/**
* @ORMEntity(repositoryClass="AppBundleRepositoryFoodAnalyticsUserIngredientSupplierRepository")
*/
class UserIngredientSupplier
{
use TimestampableEntity;

/**
* @ORMId
* @ORMColumn(type="integer", length=11)
* @ORMGeneratedValue(strategy="AUTO")
*/
private $id;

/**
* @ORMColumn(type="decimal", precision=10, scale=2, nullable=true)
*/
private $quantity;

/**
* @ORMColumn(type="decimal", precision=10, scale=2, nullable=true)
*/
private $cost;

/**
* @ORMManyToOne(targetEntity="AppBundleEntityFoodAnalyticsUnit")
* @ORMJoinColumn(name="unitId", referencedColumnName="id", nullable=false, onDelete="restrict")
*/
private $unit;

/**
* @ORMManyToOne(targetEntity="AppBundleEntityFoodAnalyticsUserSupplier", inversedBy="userIngredientSuppliers")
* @ORMJoinColumn(name="organizationId", referencedColumnName="id", nullable=true, onDelete="cascade")
*/
private $userSupplier;

/**
* @ORMManyToOne(targetEntity="AppBundleEntityFoodAnalyticsUserIngredient", inversedBy="userIngredientSuppliers")
* @ORMJoinColumn(name="userIngredientId", referencedColumnName="id", nullable=false, onDelete="cascade")
*/
private $userIngredient;/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set quantity
*
* @param string $quantity
*
* @return UserIngredientSupplier
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;

return $this;
}

/**
* Get quantity
*
* @return string
*/
public function getQuantity()
{
return $this->quantity;
}

/**
* Set cost
*
* @param string $cost
*
* @return UserIngredientSupplier
*/
public function setCost($cost)
{
$this->cost = $cost;

return $this;
}

/**
* Get cost
*
* @return string
*/
public function getCost()
{
return $this->cost;
}

/**
* Set userSupplier
*
* @param AppBundleEntityFoodAnalyticsUserSupplier $userSupplier
*
* @return UserIngredientSupplier
*/
public function setUserSupplier(AppBundleEntityFoodAnalyticsUserSupplier $userSupplier = null)
{
$this->userSupplier = $userSupplier;

return $this;
}

/**
* Get userSupplier
*
* @return AppBundleEntityFoodAnalyticsUserSupplier
*/
public function getUserSupplier()
{
return $this->userSupplier;
}

/**
* Set userIngredient
*
* @param AppBundleEntityFoodAnalyticsUserIngredient $userIngredient
*
* @return UserIngredientSupplier
*/
public function setUserIngredient(AppBundleEntityFoodAnalyticsUserIngredient $userIngredient)
{
$this->userIngredient = $userIngredient;

return $this;
}

/**
* Get userIngredient
*
* @return AppBundleEntityFoodAnalyticsUserIngredient
*/
public function getUserIngredient()
{
return $this->userIngredient;
}

/**
* Set unit
*
* @param AppBundleEntityFoodAnalyticsUnit $unit
*
* @return UserIngredientSupplier
*/
public function setUnit(AppBundleEntityFoodAnalyticsUnit $unit)
{
$this->unit = $unit;

return $this;
}

/**
* Get unit
*
* @return AppBundleEntityFoodAnalyticsUnit
*/
public function getUnit()
{
return $this->unit;
}
}

0

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]