2

nm関係をサポートするために、shelf、section、shelf_has_section中間テーブルの3つのテーブルがあります。symfony doctrine: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:
  class: Section
  refClass: ShelfHasSection
  local: shelf_id

単に、利用可能なセクションのチェックボックスのリストをチェックして、チェックしたセクションの本の数を追加するようなものです。

embedRelation()などで作成しようとしましたが、symfonyの知識が不足しているためにそこに到達できません。どんな助けでも大歓迎です。

4

2 に答える 2

2

理論的には、nmリレーションテーブルに独自のフィールドがある場合、それ自体がエンティティになるため、nmリレーションのドクトリンモデルはこの問題と一致しません...しかし:-まず、スキーマを再定義して、foreignAliasesをに追加する必要があります。 nmエンティティ:

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には、セクションのオートコンプリートフィールドと、書籍数の入力が含まれる場合があります。したがって、シェルフを1つのセクションに関連付ける場合は、(プラグインを使用して)1つのフォームを追加し、値を選択します。最新の問題は、セクションの重複を回避する方法にあります。ウィッチセクションがすでに関連していることを記憶し、オートコンプリートクエリで送信するために、JavaScriptフィルターを適用する必要があると思います。そのため、ドクトリンクエリはこのセクションを除外できます。非常に厄介で、そうですが、私が理解できる唯一の解決策です。

ジェネレーターを使用していないが、いくつかのカスタムアクション/テンプレートを使用している場合、問題はより簡単になると思います。1つのCustomShelfHasSectionFormをシェルフフォームに埋め込みます(セクションごとに1つ)。次に、各フォームに1つのチェックボックスウィジェット(おそらく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();
   }

}

これはすべて「オンエア」コードであるため、おそらく何かがうまく機能しない可能性があります。たぶん、あなたはこの解決策の1つを試すことができます、そしてそれがあなたのためにどのように働くかを私たちに知らせてください。これがお役に立てば幸いです。

于 2012-09-27T18:19:18.117 に答える
0

そのような行動を求めるのはあなたが初めてではありません。残念ながら、symfony はリレーション テーブル内の余分なフィールドを処理するようには設計されていません。

過去に一度やったことがありますが、それに関するソースコードが見つかりません。しかし、これはembedRelationで扱うのが難しい一種のハックであることを覚えています.

Web で役立つトピックをいくつか見つけました (少なくとも出発点としては)。

最初のリンクでは、johandoumaには適切な解決策があるようですが、投稿されていません。あなたはに連絡して、彼が解決策を覚えているかどうかを確認するかもしれません..

于 2012-09-26T09:22:53.187 に答える