Symfony 1.4/doctrine schema.yml отношения многие ко многим не работают должным образом?

У меня есть небольшая тревожная проблема здесь! использование Symfony 1.4 с Doctrine! на самом деле у меня есть отношение «многие ко многим» (см. код ниже), но у меня нет ПРАВИЛЬНОГО результата!

     Monitor:
  actAs:
    Timestampable: ~
  columns:
    label: {type: string(45)}
    url: {type: string(80)}
    frequency: {type: integer}
    timeout: {type: integer}
    method: {type: enum, values: [GET, POST]}
    parameters: {type: string(255)}
  relations:
    Server:
      foreignAlias: Servers
      refClass: Benchmark
      local: monitor_id
      foreign: server_id

Server:
  actAs:
    Timestampable: ~
  columns:
    name: string(255)
    ip: string(255)
  relations:
     Monitor:
      foreignAlias: Monitors
      refClass: Benchmark
      local: server_id
      foreign: monitor_id

Benchmark:
  actAs:
    Timestampable: ~
  columns:
    monitor_id: { type: integer, primary: true }
    server_id: { type: integer, primary: true }
    connexionTime: {type: string(45)}
    executionTime: {type: string(45)}
    responseTime: {type: string(45)}
    responseCode: {type: string(45)}
    responseMessage: {type: string(45)}
  relations:
    Monitor:
      local: monitor_id
      foreign: id
      foreignAlias: Monitors
    Server:
      local: server_id
      foreign: id
      foreignAlias: Servers

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

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

500 | Internal Server Error | Doctrine_Connection_Mysql_Exception
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`sfmonitoring`.`benchmark`, CONSTRAINT `benchmark_monitor_id_monitor_id` FOREIGN KEY (`monitor_id`) REFERENCES `monitor` (`id`))

у меня есть этот код в классе BaseBenchmarkForm

    abstract class BaseBenchmarkForm extends BaseFormDoctrine
{
  public function setup()
  {
    $this->setWidgets(array(
      'monitor_id'      => new sfWidgetFormInputHidden(),
      'server_id'       => new sfWidgetFormInputHidden(),
      'connexionTime'   => new sfWidgetFormInputText(),
      'executionTime'   => new sfWidgetFormInputText(),
      'responseTime'    => new sfWidgetFormInputText(),
      'responseCode'    => new sfWidgetFormInputText(),
      'responseMessage' => new sfWidgetFormInputText(),
      'created_at'      => new sfWidgetFormDateTime(),
      'updated_at'      => new sfWidgetFormDateTime(),
    ));

    $this->setValidators(array(
      'monitor_id'      => new sfValidatorChoice(array('choices' => array($this->getObject()->get('monitor_id')), 'empty_value' => $this->getObject()->get('monitor_id'), 'required' => false)),
      'server_id'       => new sfValidatorChoice(array('choices' => array($this->getObject()->get('server_id')), 'empty_value' => $this->getObject()->get('server_id'), 'required' => false)),
      'connexionTime'   => new sfValidatorString(array('max_length' => 45, 'required' => false)),
      'executionTime'   => new sfValidatorString(array('max_length' => 45, 'required' => false)),

ЛЮБЫЕ ИДЕИ РЕБЯТА?????? Пожалуйста, я действительно заблокирован!

############################################### V2

Спасибо за помощь, это действительно важно для меня! Я сделал эти преобразования:

 Monitor:
      tableName: monitor
      actAs:
        Timestampable: ~
      columns:
        label: {type: string(45)}
        url: {type: string(80)}
        frequency: {type: integer}
        timeout: {type: integer}
        method: {type: enum, values: [GET, POST]}
        parameters: {type: string(255)}

    Benchmark:
      actAs:
        Timestampable: ~
      columns:
        monitor_id: { type: integer, primary: true }
        server_id: { type: integer, primary: true }
        connexionTime: {type: string(45)}
        executionTime: {type: string(45)}
        responseTime: {type: string(45)}
        responseCode: {type: string(45)}
        responseMessage: {type: string(45)}
      relations:
        Monitor: { onDelete: CASCADE, local: monitor_id, foreign: id, foreignAlias: Monitors }
        Server: { onDelete: CASCADE, local: server_id, foreign: id, foreignAlias: Servers }

    Server:
      actAs:
        Timestampable: ~
      columns:
        name: string(255)
        ip: string(255)  

Но в «новом» интерфейсе эталона я все еще не получаю список серверов и мониторов!


person ProXamer    schedule 05.08.2011    source источник
comment
я изменил свой вопрос, пожалуйста, прочитайте его, я не получил правильного результата в новом интерфейсе теста!   -  person ProXamer    schedule 05.08.2011


Ответы (2)


Хорошо, возьмем два: ошибка (SQL), которую вы получаете, означает, что Benchmark, который вы хотите сохранить, имеет недопустимый monitor_id. Так что он либо пуст, либо относится к несуществующему монитору.

Вероятно, это происходит из-за того, что вы не выбрали монитор/сервер, потому что они были невидимы в форме (они отображаются как sfWidgetFormInputHidden). Чтобы показать <select> для этих двух, вам нужно перейти к BenchmarkForm (который переопределяет BaseBenchmarkForm и переопределяет метод configure(). Что-то вроде этого:

public function configure() {
  parent::configure();
  $this->widgetSchema['monitor_id'] = sfWidgetFormDoctrineChoice(array('model' => 'Monitor'));
  $this->widgetSchema['server_id'] = sfWidgetFormDoctrineChoice(array('model' => 'Server'));

  $this->validatorSchema['monitor_id'] = sfValidatorDoctrineChoice(array('model' => 'Monitor'));
  $this->validatorSchema['server_id'] = sfValidatorDoctrineChoice(array('model' => 'Server'));

}
person Grad van Horck    schedule 08.08.2011
comment
при отправке бенчмарка пишет, что значения монитора и сервера в поле недействительны - person ProXamer; 08.08.2011
comment
Также необходимо обновить валидаторы. См. мой обновленный пример кода. :-) (И не забудьте принять мой ответ, если он работает ;-)) - person Grad van Horck; 08.08.2011
comment
Если да! пожалуйста, у меня есть другая проблема таким же образом, но с таблицей SfGuardGroup, которую я использую в отношении многие ко многим! Я опубликую это через несколько минут! - person ProXamer; 08.08.2011

Ваше определение refClass в отношениях Server может указывать только на модель с двумя полями: по одному полю для каждой из сторон-владельцев (в данном случае Server и Monitor). Создавая отношение «многие ко многим» таким образом, вы можете вызвать $server->Monitors и автоматически использовать этот refClass для создания коллекции Monitor (а не Benchmark). (Как пользователь вы не видите refClass).

Если вы хотите иметь больше данных в этом «классе связи» Benchmark, как и вы, вам придется поработать над разделением отношений.

Просто поместите отношение на сервер, и, вероятно, все будет готово.

person Grad van Horck    schedule 05.08.2011
comment
Пожалуйста, прочитайте вопрос, который я изменил, потому что я все еще не могу воспроизвести свои вопросы! - person ProXamer; 05.08.2011