开发者

Symfony 1.4/doctrine schema.yml many to many relations does'nt work properly?

I have a little disturbing problem in here! an using symfony 1.4 with Doctrine! i fact i have a "many to many" relation (see code bellow) but i don't have the RIGHT result!

     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- when in the add server (or monitor) interface there is a list of monitors (or servers) that appears (but i can add a server(or monitor) without selecting it.

2- when in the add benchmark interface, i don't have the monitors and servers list in order to select them! and when i submit i doesn't work (it should'nt any way!). i get this error:

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`))

i have this code in the BaseBenchmarkForm class

    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)),

ANY IDEAS GUYS ?????? Pleaaaaaase am really Blocked !

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

Thank you for the Help, it really means to me! I did theses transformations:

 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)  开发者_如何学C

But in the benchmark "new" interface, i still don't get the servers and the monitors list!


Okay, take two: The (SQL) error your getting means that the Benchmark you want to save, has an invalid monitor_id. So it's either empty or refers to a non-existing monitor.

This probably happens because you didn't select a monitor/server, because they were invisible on the form (they are rendered as sfWidgetFormInputHidden). To show the <select>s for these two, you have to go to the BenchmarkForm (which overrides the BaseBenchmarkForm, and override the configure() method. Something like this:

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'));

}


Your refClass definition in the Server relations, can only point to a model with two fields: one field for each of the owning sides (in this case Server and Monitor). By creating a Many-To-Many relation this way, you can call $server->Monitors, and automatically uses this refClass to create a collection of Monitor (and not Benchmark). (As a user you don't see the refClass).

If you want to have more data in this 'coupling class' Benchmark, like you do, you'll have to work with to separate relations.

Just drop the relation in the Server and you'll probably be done.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜