2

有3个表:shelf、section和shelf_has_section中间表来支持nm关系。从 symfony 学说构建的模式:build-schema 如下所示。

简单地,

shelf(id, position)
section(id, name)
shelf_has_section(shelf_id, section_id, number_of_books)

架构。

Shelf:
  connection: doctrine
  tableName: shelf
  columns:
    id:
      type: integer(4)
      fixed: false
      unsigned: true
      primary: true
      autoincrement: true
    position:
      type: string(255)
      primary: false
      notnull: true
      autoincrement: false
  relations:
    ShelfHasSection:
      local: id
      foreign: shelf_id
      type: many

Section:
  connection: doctrine
  tableName: section
  columns:
    id:
      type: integer(1)
      primary: true
      autoincrement: false
    name:
      type: string(20)
      primary: false
      notnull: true
  relations:
    ShelfHasSection:
      local: id
      foreign: section_id
      type: many

ShelfHasSection:
  connection: doctrine
  tableName: shelf_has_section
  columns:
    shelf_id:
      type: integer(4)
      primary: true
      autoincrement: false
    section_id:
      type: integer(1)
      primary: true
      autoincrement: false
    number_of_books:
      type: integer(4)
      primary: false
      notnull: false
      autoincrement: false
  relations:
    Shelf:
      local: shelf_id
      foreign: id
      type: one
    Section:
      local: section_id
      foreign: id
      type: one

通过在架构中添加以下与 Shelf 的关系,我设法将 Sections 显示为复选框列表。我还需要在部分复选框前面显示一个文本字段以输入书籍数量。

Sections:
  class: Section
  refClass: ShelfHasSection
  local: shelf_id

就像检查可用部分的复选框列表并添加已检查部分的书籍数量一样。

我试图通过 embedRelation() 等实现它,但缺乏我的 symfony 知识并没有让我到达那里。任何帮助高度赞赏。

4

2 回答 2

2

从理论上讲,如果一个 nm 关系表有它自己的字段,它本身就成为一个实体,因此 nm 关系的学说模型不匹配这个问题......但是: - 首先,您必须重新定义您的架构以添加 foreignAliases纳米实体:

ShelfHasSection:
  connection: doctrine
  tableName: shelf_has_section
  columns:
    shelf_id:
      type: integer(4)
      primary: true
      autoincrement: false
    section_id:
      type: integer(1)
      primary: true
      autoincrement: false
    number_of_books:
      type: integer(4)
      primary: false
      notnull: false
      autoincrement: false
  relations:
    Shelf:
      local: shelf_id
      foreign: id
      type: one
      **foreignAlias: ShelfHasSections**
    Section:
      local: section_id
      foreign: id
      type: one
      **foreignAlias: ShelfHasSections**

如果您试图使其在生成的模块上工作,那么您的复选框想法没有解决方案。我建议您使用 ahDoctrineEasyEmbeddedRelationsPlugin,并将关系 ShelfHasSections 嵌入到您的货架表单中。插件嵌入的 ShelfHasSectionForm 可能具有该部分的自动完成字段,以及书籍数量的输入。因此,当您想将某个架子与一个部分相关联时,添加一个表单(使用插件)并选择值。最新的问题变成了如何避免重复的部分......我想你应该应用一些 javascript 过滤器来记住女巫部分已经相关并与自动完成查询一起发送,所以学说查询可以排除这些部分......听起来非常讨厌,确实如此,但这是我能想出的唯一一种解决方案。

如果您不使用生成器,而是使用一些自定义操作/模板,我想问题会变得更容易:将 1 个 CustomShelfHasSectionForm 嵌入到您的货架表单(每个部分一个)。然后,在每个表单中添加一个复选框小部件(可能带有 sfWidgetFormInputCheckbox)以选择关系。他们在处理表单时会删除那些没有选中复选框的嵌入表单。像这样的东西:

class CustomShelfHasSectionForm extends ShelfHasSectionForm {
 public function configure() {
   unset($this['shelf_id']);
   $this->widgetSchema['selected'] = new sfWidgetFormInputCheckbox();
   $this->validatorSchema['selected'] = new sfValidatorBoolean(array('required' => false));
 }

}

class CustomShelfForm extends ShelfForm {
  private $unselected_sections = array();
  public function configure() {

    $sections = Doctrine::getTable('Section')->findAll();
    foreach($sections as $section) {
      $shelfHasSection = new ShelfHasSection();
      $shelfHasSection->setShefl($this->getObject());
      $shelfHasSection->setSection($section);
      $this->embedForm('section_'.$section->getId(), new CustonShelfHasSectionForm($shelfHasSection));
    }

  }


  public function doBind(array $values) {
    $sections = Doctrine::getTable('Section')->findAll();
    foreach($sections as $section) {
       // Do some debug with print_r($values) to find something like
       ...
       if(empty($values['section_'.$section->getId()]['selected']) {
          $this->unselected_sections[] = $section->getId();

       }
    }
    return parent::doBind($values);
  }

  public function doSave($con = null) {
       foreach($this->unselected_sections as $section_id) {
          // disembed form, something like
          unset($this->embeddedForms["section_".$section->getId()]);
       }
  }
}

然后,在你的 action.class.php

$shelfObject = ....
$this->form = new CustomShelfForm($shelfObject);
if(....) { 
   $this->form->bind...
   if($this->form->isValid()) {
      $this->form->save();
   }

}

这都是“播出”的代码,所以可能有些东西不能很好地工作。也许您可以尝试其中一种解决方案,让我们知道它是如何为您工作的。我希望这可以帮助你。

于 2012-09-27T18:19:18.117 回答
0

你不是第一个提出这种行为的人。遗憾的是,symfony 并没有被设计用来处理关系表中的额外字段。

我过去做过一次,但我找不到有关它的源代码。但我记得这是一种很难用 embedRelation 处理的 hack。

我在网上发现了一些可能对您有所帮助的主题(至少作为一个起点):

在第一个链接中,johandouma似乎有一个合适的解决方案,但没有发布。你可以联系,看看他是否记得解决方案。

于 2012-09-26T09:22:53.187 回答