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 !
############################################### V2Thank 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.
精彩评论