querybuilder form fields array php symfony1 doctrine symfony-1.4 symfony-forms

php - fields - Symfony Generator Forms, Doctrine y M: N Relationships



symfony form querybuilder (2)

Hace aproximadamente 10 meses tuve problemas similares con las relaciones M: N y los metadatos en la tabla de unión.

¡Encontré esas entradas de blog de Melikedev muy útiles! Esto no es exactamente lo mismo que su caso de uso, pero podría darle algunas pistas:

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/

Tengo una configuración M: N básica con tres tablas: candidato, posición y candidate_position.

Aquí hay una captura de pantalla del ERD de MySQL Workbench

Ahora, pasando de eso, hablemos de formas. En el mundo predeterminado del generador de Symfony, tendrías una interfaz CRUD separada para las tres de estas tablas. Sin embargo, no quiero tener una interfaz CRUD para candidate_position .

Lo que quiero es que las acciones de creación y edición de la interfaz candidata contengan un campo de opción múltiple (lista de selección, matriz de casillas, lo que sea) que crearía los registros CandidatePosition como parte de las acciones candidatas.

En el código

config / doctrine / schema.yml (Nota: el no es el esquema completo.yml, sino solo las tablas que se tratan aquí)

--- 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]

aplicaciones / backend / modules / candidate / config / 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: ~

lib / form / doctrine / 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 ) ); } }

Todo esto funciona, excepto cuando se trata de guardar los datos. Este es el punto donde me quedo atascado.

Claramente necesito hacer algo para crear / editar / eliminar los registros CandidatePosition, pero no estoy seguro por dónde empezar a trabajar. En candidateActions ? Anular Basecandidate::save() ?

Avíseme si hay otros datos que pueda necesitar ver.

  • PHP 5.2.x
  • Symfony 1.4.3

antes que nada, puedo sugerir una actualización de la versión de Symfony; utilizo 1.4.11 donde tendrás esta funcionalidad funcionando desde cero.

Si esto no es posible en su caso, el mejor lugar para esto será anular el método base doSave () en candidateForm así:

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

y también es probable que necesite establecer manualmente el objeto de enlace seleccionado en la carga de formulario de esta manera:

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

Esto debería funcionar.

ACTUALIZAR

Creo que dado que la actualización a la 1.4.11 no ayuda, hay un problema con la definición del esquema y mi suposición es que debe agregar la definición de relación a la tabla de enlace ''candidatePosition'' de esta manera:

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

Espero que esto ayude.

Saludos.