Symfony sfWidgetFormDoctrineChoice с несколькими опциями

Я создал форму, в которую я вставляю другую форму. Мой вопрос касается этой встроенной формы. Я использую виджет sfWidgetFormDoctrineChoice с множественным параметром, установленным в true. Код метода настройки этой встроенной формы:

public function configure()
  {
    unset($this['prerequisite_id']);
    $this->setWidget('prerequisite_id', new sfWidgetFormDoctrineChoice(array(
        'model' => 'Stage',
        'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
        'multiple' => true
    )));

    $this->setValidator('prerequisite_id', new sfValidatorDoctrineChoice(array(
        'model' => 'Stage',
        'multiple' => true,
        'query' => Doctrine_Query::create()->select('s.id, s.name')->from('Stage s')->where('s.workflow_id = ?', $this->getOption('workflow_id') ),
        'column' => 'id'
    )));
  }

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

Я получаю это предупреждение PHP после отправки формы:

Предупреждение: strlen() ожидает, что параметр 1 будет строкой, массивом, указанным в D:\Development\www\flow_dms\lib\vendor\symfony\lib\plugins\sfDoctrinePlugin\lib\database\sfDoctrineConnectionProfiler.class.php в строке 198.

и еще - я знаю, почему - в режиме отладки symfony я вижу в трассировке стека следующее:

at Doctrine_Connection->exec('ВСТАВИТЬ В stage_has_prerequisites (prerequisite_id, stage_id) VALUES (?,?)', array(array('12', '79'), '103'))

Итак, что делает Symfony, так это отправляет в Doctrine массив вариантов, и, как я вижу в отладочном sql-запросе, Doctrine не может правильно отобразить запрос.

Есть идеи, как это исправить? Мне нужно было бы сгенерировать два запроса для двух вариантов:

INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (12, 103);
INSERT INTO stage_has_prerequisites (prerequisite_id, stage_id) VALUES (79, 103);

stage_id всегда одно и то же (я имею в виду, что оно задается вне этой формы формой, в которую оно встроено).

Я уже потратил 4 часа на проблему, так что, возможно, кто-то сможет помочь.


person XanatosLightfiren    schedule 04.01.2012    source источник
comment
Вместо редактирования вопроса, на который вы можете ответить, можно принять ответ.   -  person Arasu    schedule 05.01.2012


Ответы (1)


Что ж, кажется, я нашел решение (хотя и не самое лучшее, наверное). Надеюсь, это будет полезно для кого-то.

Наконец, после долгих размышлений, я пришел к выводу, что если проблема возникает из-за того, что Doctrine_Record не может сохранить запись, если она встречает массив вместо одного значения, то самым простым решением будет перезапись метода save() метода Doctrine_Record. И вот что я сделал:

class StageHasPrerequisites extends BaseStageHasPrerequisites
{
  public function save(Doctrine_Connection $conn = null)
  {
    if( is_array( $this->getPrerequisiteId() ) )
    {
      foreach( $this->getPrerequisiteId() as $prerequisite_id )
      {
        $obj = new StageHasPrerequisites();
        $obj->setPrerequisiteId( $prerequisite_id );
        $obj->setStageId( $this->getStageId() );
        $obj->save();
      }
    }
    else
    {
      parent::save($conn);
    }
  }

  (...)

}

Итак, теперь, если он встречает массив вместо одного значения, он просто создает временный объект и сохраняет его для каждого из значений этого массива.

Не элегантное решение, конечно, но оно работает (имейте в виду, что оно написано для конкретной структуры данных и это просто эффект моей методологии, а именно Посмотреть, что не так в режиме отладки, а затем попытаться исправить Это возможно любым способом).

person XanatosLightfiren    schedule 08.01.2012
comment
Ну, это не кажется законным решением, это просто обходной путь. Сегодня я столкнулся с той же (я так думаю) проблемой с одним из моих модулей, но в моем случае проблема возникает на общем стандартном значении. (Родительский) ForeignKey. Моя модель A имеет иностранный ключ B, и этот ключ обернут массивом(). Это больная магия доктрины, и я не знаю, в чем проблема. - person Julius F; 15.03.2012
comment
Да, это просто обходной путь, но я не нашел другого способа сделать это. - person XanatosLightfiren; 17.04.2012