Symfony 1.4 doctrine - many-to-many relationship with extra field in intermediate table

爱⌒轻易说出口 提交于 2019-12-06 11:02:18

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**

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.

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()]);
       }
  }
}

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.

You're not the first one to ask such a behavior. Sadly, symfony isn't designed to handle an extra field in the relation table.

I did it once in the past but I can't find source code about it. But I remember that this is kind of hack which is hard to handle with embedRelation.

I found few topics around the web that might help you (at least for a starting point):

In the first link, it seems that johandouma has a suitable solution but didn't post it. You might contact him to see if he remember the solution..

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!