symfony以嵌入的形式存在多对多

时间:2011-03-26 09:00:59

标签: symfony1 doctrine many-to-many relation

我有一个模型的嵌入形式的问题,它具有多对多的关系。嵌入的表单将正确保存模型,但不会保存多对多的关系。

示例:

的schema.yml:

Mother:
  columns:
    name:
      type: string(80)

Color:
  columns:
    name:
      type: string(80)

Child:
  columns:
    mother_id:
      type: integer
    name:
      type: string(80)
  relations:
    Mother:
      class: Mother
      local: mother_id
      foreign: id
      type: one
      onDelete: cascade
      foreignType: one
      foreignAlias: Children
    FavoriteColors:
      class: Color
      refClass: ChildColor
      local: child_id
      foreign: color_id
      onDelete: cascade
      foreignAlias: Children

ChildColor:
  columns:
    child_id:
      type: integer
    color_id:
      type: integer

然后我只修改MotherForm.class.php:

class MotherForm extends BaseMotherForm
{
  public function configure()
  {
    $this->embedForm('child', new ChildForm($this->getObject()->getChildren()));
  }
}

和ChildForm.class.php:

class ChildForm extends BaseChildForm
{
  public function configure()
  {
    unset($this['mother_id']);
  }
}

我使用doctrine生成模块:

php symfony doctrine:generate-module frontend mother Mother

放一些颜色数据:

Color:
  Color_1:
    name: blue
  Color_2:
    name: red
  Color_3:
    name: green
  Color_4:
    name: purple

当我打电话给/frontend_dev.php/mother/new时我可以添加一个新的,母亲和孩子的名字会更新,但最喜欢的颜色永远不会保存...

如果我使用phpmyadmin然后/编辑调用添加颜色和子项之间的关系。然后正确的颜色在选择的多个选择中,但我无法编辑它。

这是来自Symfony的错误还是我应该做些什么?

更新: 如果我为模型Child生成模块。我可以编辑喜欢的颜色,但表格不再嵌入......

1 个答案:

答案 0 :(得分:1)

我遇到了和你相同的问题。 Ticket #5867 in symfony就是这个问题,很多人都花了很多时间。

在机票中,有些人提供解决方案。你可以尝试一下,但我不知道他们为什么不能解决这个问题。

我已成功solution found in this post。这是一个非常有用的帖子,它解释了这个错误的原因和解决方法。

基本上,错误是由于以下事实:在保存嵌入式表单时,symfony在嵌入式对象中调用save(),而不是在嵌入式表单中,并且对象中的save()不会更新相关表格。

要解决这个问题,你必须覆盖//lib/form/doctrine/BaseFormDoctrine.class.php(或Propel等价物,但在下面的代码中替换Doctrine for Propel):

以这种方式创建函数bindEmbeddedForms()

public function bindEmbeddedForms($embedded_forms, $values)
{
  if($this->isValid())
  {
    foreach ($embedded_forms as $name => $form)
    {
      $form->isBound = true;
      $form->values = $values[$name];

      if ($form->embeddedForms)
      {
        $this->bindEmbeddedForms($form->embeddedForms, $values[$name]);
      }
    }
  }
}

声明bind()函数以这种方式调用其父类:

public function bind(array $taintedValues = null, array $taintedFiles = null)
{
   parent::bind($taintedValues, $taintedFiles);
   $this->bindEmbeddedForms($this->embeddedForms, $this->getValues());
}

以这种方式覆盖saveEmbeddedForms()

public function saveEmbeddedForms($con = null, $forms = null)
{
  if (is_null($con))
  {
    $con = $this->getConnection();
  }

  if (is_null($forms))
  {
    $forms = $this->embeddedForms;
  }

  foreach ($forms as $key => $form)
  {
    if ($form instanceof sfFormDoctrine)
    {
      if(method_exists(new $form(), 'doSaveManyToMany'))
      {
        $form->doSaveManyToMany($con);
      }
      else
      {
        $form->getObject()->save($con);
      }
      $form->saveEmbeddedForms($con);
    }
    else
    {
      $this->saveEmbeddedForms($con, $form->getEmbeddedForms());
    }
  }
}

然后,在你的嵌入式表单类中(在帖子中它也在BaseFormDoctrine类中执行此操作,但我认为它更简洁),创建保存关系的方法doSaveManyToMany: / p>

public function doSaveManyToMany($con = null)
{
  if (is_null($con))
  {
    $con = $this->getConnection();
  }

  $this->object->save($con);
  /*
  * Save the many-2-many relationship
  */
  $this->save***List($con); //Ex: $this->saveAhasBList($con)
}

有些人说在帖子评论中遇到一些问题并提出解决方案,但这不是我的理由。

希望它对某人有所帮助,即使我的回答是针对一个相当陈旧的问题。