【问题标题】:symfony2 embedded form collection and entity mappingsymfony2 嵌入式表单集合和实体映射
【发布时间】:2015-11-16 09:17:37
【问题描述】:

我正在关注 symfony2 关于如何创建嵌入式表单集合的教程,但无法实现它,因为它只创建了一个联结表。

根据学说2文档: “为什么多对多关联不太常见?因为你经常想将附加属性与关联关联,在这种情况下你引入关联类。因此,直接多对多关联消失了,取而代之的是一个—— 3 个参与类之间的多对多/多对一关联。”

这是我的代码的一些 sn-ps:

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';
}
}

这行得通,我确实得到了一个嵌入式表单集合,但问题是成分营养表中的成分 ID 为空。如何使用正确的 ID 填充表格?

这些是我在页面上得到的字段:

姓名:

营养:

数量:

单位:

这个想法是,如果我将成分营养素表单与成分表单绑定,则用户不必指定成分名称两次。

谢谢。

【问题讨论】:

    标签: php forms symfony doctrine-orm


    【解决方案1】:

    首先,您需要“交叉引用”您的实体:

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

    确保关系的双方都已设置。这将解决 null id 问题。

    另一个问题是您在 Ingrediant/Nutrient 实体中使用集合,但您的 set 方法没有使用数组运算符。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-05
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多