Формы Symfony Generator, доктрина и отношения M: N - PullRequest
0 голосов
/ 10 июня 2011

У меня есть базовая установка M: N с тремя таблицами: кандидат, позиция и кандидат_позиция.

Вот скриншот ERD от MySQL Workbench

http://dl.dropbox.com/u/180411/stackoverflow/erd.png

Теперь, переходя от этого, давайте поговорим о формах. В стандартном мире генератора Symfony у вас будет отдельный интерфейс CRUD для всех этих трех таблиц. Однако я не хочу иметь CRUD-интерфейс для candidate_position.

Я хочу, чтобы действия по созданию и редактированию интерфейса кандидата содержали поле с несколькими вариантами выбора (список выбора, массив флажков и т. Д.), Которое создавало бы записи CandidatePosition как часть действий кандидата.

На коду

config / doctrine / schema.yml (Примечание: это не весь schema.yml, а только обсуждаемые здесь таблицы)

---
detect_relations: true
options:
  type: InnoDB

candidate:
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    first_name:
      type: string(45)
      notnull: true
    last_name:
      type: string(45)
      notnull: true
    created_at:
      type: integer(4)
      unsigned: true
  relations:
    Positions:
      class: Position
      refClass: CandidatePosition
      local: candidate_id
      foreign: position_id

position:
  columns:
    id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
      autoincrement: true
    name:
      type: string(45)
  relations:
    Candidates:
      class: Candidate
      refClass: CandidatePosition
      local: position_id
      foreign: candidate_id


candidatePosition:
  tableName: candidate_position
  columns:
    candidate_id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
    position_id:
      type: integer(4)
      primary: true
      unsigned: true
      notnull: true
  indexes:
    fk_candidate_position_candidate1:
      fields: [candidate_id]
    fk_candidate_position_position1:
      fields: [position_id]

приложения / бэкэнда / модули / кандидат / конфиг / generator.yml

generator:
  class: sfDoctrineGenerator
  param:
    model_class:           Candidate
    theme:                 admin
    non_verbose_templates: true
    with_show:             false
    singular:              ~
    plural:                ~
    route_prefix:          candidate
    with_doctrine_route:   true
    actions_base_class:    sfActions

    config:
      actions: ~
      fields:  
        first_name: { label: First Name }
        last_name:  { label: Last Name }
        created_at: { label: Created On }
        candidate_positions:  {label: Positions}
      list:    
        sort:  [last_name, asc]
      filter:  ~
      form:    
        display:
          "User": [first_name, last_name]
          "Applying For": [candidate_positions]
        fields :
          hide:  [created_at]
      edit:    ~
      new:     ~

Библиотека / форма / учение / candidateForm.class.php

class candidateForm extends BasecandidateForm
{
  public function configure()
  {
    unset( $this['created_at'] );

    $this->widgetSchema['candidate_positions'] = new sfWidgetFormDoctrineChoice(
      array( 'multiple' => true, 'model' => 'Position', 'renderer_class' => 'sfWidgetFormSelectCheckbox' )
    );

    $this->validatorSchema['candidate_positions'] = new sfValidatorDoctrineChoice(
      array( 'multiple' => true, 'model' => 'Position', 'min' => 1 )
    );
  }
}

Это все работает, кроме случаев, когда дело доходит до фактического сохранения данных. Это та точка, в которой я застреваю.

Я явно должен сделать что-то , чтобы создать / отредактировать / удалить записи CandidatePosition, но я не уверен, с чего начать. В candidateActions? Переопределить Basecandidate::save()?

Дайте мне знать, если вам понадобятся какие-либо другие данные.

  • PHP 5.2.x
  • symfony 1.4.3

Ответы [ 2 ]

1 голос
/ 11 июня 2011

Около 10 месяцев назад у меня возникла аналогичная проблема с отношениями M: N и метаданными в таблице соединений.

Я нашел эти записи в блоге melikedev очень полезными! Это не совсем то же самое, что ваш вариант использования, но он может дать вам несколько советов:

http://melikedev.com/2009/12/09/symfony-w-doctrine-saving-many-to-many-mm-relationships/

http://melikedev.com/2009/12/06/symfony-sfformextraplugin-select-double-list-maintain-order/

http://melikedev.com/2010/04/06/symfony-saving-metadata-during-form-save-sort-ids/

0 голосов
/ 12 июня 2011

Прежде всего я могу предложить обновить версию Symfony - я использую 1.4.11, где у вас будет эта функциональность, работающая с нуля.

Если это невозможно в вашем случае, лучшее место для этого - переопределить базовый метод doSave () вандидатской формы следующим образом:

protected function doSave($con = null)
{
    $existing = $this->object->Position->getPrimaryKeys();
    $values = $this->getValue('candidate_positions');

    $unlink = array_diff($existing, $values);
    $this->object->unlink('Position', array_values($unlink));

    $link = array_diff($values, $existing);
    $this->object->link('Position', array_values($link));

    parent::doSave($con);
}

, а также вам, вероятно, потребуется вручную установить выбранный объект ссылки при загрузке формы следующим образом:

public function updateDefaultsFromObject()
{
    parent::updateDefaultsFromObject();

    if (isset($this->widgetSchema['candidate_positions']))
    {
        $this->setDefault('candidate_positions', $this->object->Position->getPrimaryKeys());
    }
}

Это должно сработать.

UPDATE

Я думаю, что, поскольку обновление до 1.4.11 не помогает, существует некоторая проблема с определением схемы, и я предполагаю, что вам нужно добавить определение отношения, чтобы связать таблицу'андидатское положение 'следующим образом:

  relations:
    Candidate:
      class: Candidate
      local: candidate_id
      foreign: id
      foreignAlias: Candidates
    Position:
      class: Position
      local: position_id
      foreign: id
      foreignAlias: Positions

Надеюсь, это поможет.

Привет.

...