Symfony 1.4原则 - 与中间表中的额外字段的多对多关系 [英] Symfony 1.4 doctrine - many-to-many relationship with extra field in intermediate table

查看:197
本文介绍了Symfony 1.4原则 - 与中间表中的额外字段的多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有3个表格:shelf,section和shelf_has_section中间表,以支持n-m关系。从symfony doctrine构建模式:build-schema如下所示。

There are 3 tables: shelf, section and shelf_has_section intermediate table to support n-m relation. The schema build from symfony doctrine:build-schema looks as following.

只需

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显示为复选框列表。我还需要显示文本字段前面的部分复选框才能输入书籍数量。

I managed to show Sections as a check box list through adding the following relation to Shelf in the schema. I also need to display a text field infront of section check box in order to enter number of books.

Sections:
  class: Section
  refClass: ShelfHasSection
  local: shelf_id

只是这样检查可用部分的复选框列表,并添加检查部分的书数。

Simply it's like checking the list of checkboxes for available sections and add the number of books for section checked.

我试图通过embedRelation()等来实现,但是缺乏我的symfony知识并没有让我在那里。

I tried to make it through embedRelation() etc, but lack of my symfony knowledge doesn't get me there. Any help highly appreciated.

推荐答案

理论上说,如果一个nm关系表有自己的字段,它就成为一个实体本身nm关系的原则模型与此问题不匹配,但是:
- 首先,您必须重新定义您的模式以向nm实体添加foreignAliases:

Theoretically speaking, if an n-m relation table has it own field, it becomes an entity itself, so the doctrine model for n-m relation doesn't match this problem... but: - First, you must to redefine your schema to add foreignAliases to n-m entity:

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过滤器来记住女巫部分已经相关,并发送它与自动完成查询,所以教条查询可以排除这个部分。 ...听起来很讨厌,但它是唯一的一个可以解决的解决方案。

If your are trying to make it work on a generated module, your checkboxes idea has no solution. I'll suggest you to use the ahDoctrineEasyEmbeddedRelationsPlugin, and embed the relation ShelfHasSections to your shelf form. The ShelfHasSectionForm embed by the plugin may have an autocomplete field for the section, and the input for the number of books. So, when you want to relate some shelf to one section, add one form (using the plugin) and select the values. The latest problem become on how to avoid duplicate sections.... I guess you should apply some javascript filter to remember witch section are already related and send it with the autocomplete query, so the doctrine query could exclude this sections.... Sounds very nasty, and it is, but it's the only one solution I can figure out.

如果你不使用生成器,但是一些自定义操作/模板,我想这个问题变得更容易:
将1个CustomShelfHasSectionForm嵌入到您的Shelf表单中(每个部分一个)。然后,添加一个复选框小部件(可能与sfWidgetFormInputCheckbox)它的每个表单来选择关系。他们,处理表单删除那些嵌入的表单,没有复选框被选中。有点像:

If you not using a generator, but some custom actions/template, I guess the problem become easier: Embed 1 CustomShelfHasSectionForm to your Shelf Form (one for each section). Then, add one checkbox widget (maybe with sfWidgetFormInputCheckbox) it each form to select the relation or not. Them, processing the form remove those embedded form wich no checkbox selected. Somethig like:

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

Then, in your action.class.php

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

}

这是所有的空中代码,所以可能一些事情不行。也许你可以尝试这个解决方案之一,让我们知道它如何适用于你。我希望这可以帮助你。

This is all "on the air" code, so probably something doesn't work so well. Maybe you can try one of this solutions an let us know how it works for you. I hope this can helpyou.

这篇关于Symfony 1.4原则 - 与中间表中的额外字段的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆