duanhuan8983 2015-11-16 09:17
浏览 47
已采纳

symfony2嵌入式表单集合和实体映射

I was following the symfony2 tutorial on how to create an embedded form collection but wasn't able to implement it since it only creates a junction table.

According to doctrine2 documentation: "Why are many-to-many associations less common? Because frequently you want to associate additional attributes with an association, in which case you introduce an association class. Consequently, the direct many-to-many association disappears and is replaced by one-to-many/many-to-one associations between the 3 participating classes."

Here are some snippets of my code:

src/AppBundle/Entity/Ingredient.php

/**
* Defines the properties of the Ingredient entity to represent the portal ingredients.
*
* @author furious_snail
*
* @ORM\Entity()
* @ORM\Table(name="ingredients")
* @UniqueEntity("name")
*/
class Ingredient
{
/**
 * @ORM\Id()
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @ORM\ManyToOne(targetEntity="IngredientCategory")
 * @ORM\JoinColumn(name="category_id", referencedColumnName="id", nullable=true)
 */
private $category;
/**
 * @ORM\Column(type="string", unique=true)
 */
private $name;
/**
 * @ORM\OneToMany(targetEntity="IngredientNutrient", mappedBy="ingredient", cascade={"persist", "remove"})
 */
private $nutrientsPer100G;

public function __construct()
{
    $this->substitute = new ArrayCollection();
    $this->nutrientsPer100G = new ArrayCollection();
}

public function getId()
{
    return $this->id;
}

public function setName($name)
{
    $this->name = $name;
}

public function getName()
{
    return $this->name;
}

/**
 * @param mixed $nutrientsPer100G
 */
public function setNutrientsPer100G($nutrientsPer100G)
{
    $this->nutrientsPer100G = $nutrientsPer100G;
}

/**
 * @return array
 */
public function getNutrientsPer100G()
{
    return $this->nutrientsPer100G;
}
}

src/AppBundle/Entity/IngredientNutrient.php

/**
 * @ORM\Entity()
 * @ORM\Table(name="ingredient_nutrient")
 */
class IngredientNutrient
{
/**
 * @ORM\Id()
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @var integer
 *
 * @ORM\ManyToOne(targetEntity="Ingredient", inversedBy="nutrientsPer100G")
 * @ORM\JoinColumn(name="ingredient_id", referencedColumnName="id", nullable=true)
 */
protected $ingredient;
/**
 * @var integer
 *
 * @ORM\ManyToOne(targetEntity="Nutrient")
 * @ORM\JoinColumn(name="nutrient_id", referencedColumnName="id", nullable=true)
 */
protected $nutrient;
/**
 * @ORM\Column(type="float")
 */
private $quantity;
/**
 * @ORM\ManyToOne(targetEntity="Unit")
 * @ORM\JoinColumn(name="unit_id", referencedColumnName="id", nullable=true)
 */
private $unit;

/**
 * @return mixed
 */
public function getId()
{
    return $this->id;
}

/**
 * @return mixed
 */
public function getIngredient()
{
    return $this->ingredient;
}

/**
 * @param mixed $ingredient
 */
public function setIngredient($ingredient)
{
    $this->ingredient = $ingredient;
}

/**
 * @return mixed
 */
public function getNutrient()
{
    return $this->nutrient;
}

/**
 * @param mixed $nutrient
 */
public function setNutrient($nutrient)
{
    $this->nutrient = $nutrient;
}

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

/**
 * @param mixed $quantity
 */
public function setQuantity($quantity)
{
    $this->quantity = $quantity;
}

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

/**
 * @param mixed $unit
 */
public function setUnit($unit)
{
    $this->unit = $unit;
}
}

src/AppBundle/Form/Type/IngredientNutrientType.php

class IngredientNutrientType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('nutrient', 'entity', array(
            'class' => 'AppBundle\Entity\Nutrient',
            'choice_label' => 'name',
            'label' => 'Nutrient',
        ))
        ->add('quantity', null, array('label' => 'Cantitate'))
        ->add('unit', 'entity', array(
            'class' => 'AppBundle\Entity\Unit',
            'choice_label' => 'unit',
            'label' => 'Unitate de masura'
        ));
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\IngredientNutrient',
    ));
}

public function getName()
{
    return 'app_ingredient_nutrient';
}
}

src/AppBundle/Form/Type/IngredientType.php

class IngredientType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('name', null, array('label' => 'Name'))
        ->add('nutrients_per_100_g', 'collection', array(
            'type' => new IngredientNutrientType(),
            'allow_add' => true,
            'label' => 'Nutrient quantity per 100g',
            'options' => array('label' => false),
        ));
}

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'AppBundle\Entity\Ingredient',
    ));
}

public function getName()
{
    return 'app_ingredient';
}
}

This works, I do get an embedded form collection but the issue is that the ingredient_id in the ingredient_nutrient table is null. How do I make it to fill the table with the right ID?

These are the fields I get on the page:

Name:

Nutrient:

Quantity:

Unit:

The idea is that if I have IngredientNutrient form tied with Ingredient form the user shouldn't have to specify ingredient name twice.

Thank you.

  • 写回答

1条回答 默认 最新

  • dousheyan0375 2015-11-16 14:02
    关注

    To start with, you need to "cross reference" your entities:

    public function setNutrientsPer100G($nutrientsPer100G)
    {
      $this->nutrientsPer100G = $nutrientsPer100G;
      $nutrientsPer100G->setIngrediant($this);
    }
    

    Make sure both sides of the relation are being set. That will take care of the null id issues.

    The other problem is that you are using collections in your Ingrediant/Nutrient entities but your set methods are not using the array operators.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算