0

I'm a bit of a symfony novice, and I'm attempting to create a system to track revisions to manufacturing specifications. I am using symfony 1.4.9 with Doctrine.

I have a one to many relationship between Specifications and Revisions. When creating a new Specification, an initial "Revision" must also be created, which holds most of the relevant data. In other words, I need to be able to create both a Specification and a connected Revision simultaneously.

I have created forms for Specifications and for Revisions. I am able to use the forms individually, and they function as expected. The forms render properly when embedded, and validate as expected. Creating a new Revision for an existing Specification works fine. My problem comes when I try to create a new Specification and its required Revision.

Revision's foreign key is Specification's primary key. That primary key does not exist until the Specification record is added to the database. The embedded form save fails with a MySQL error because the Revision's foreign key field cannot be null.

What is the best way around this? My thought is to change the schema to allow the foreign key to be null. I'll be able to save the forms, then do a query based on the form's values to determine what the new Specification's primary key got set to, THEN I should be able to set the related Revision's foreign key to that value. This seems ridiculously convoluted though, and will result in two extra queries than what it seems should really be required.

The easy way I can think to do it is to stop trying to use the embedded form functionality and switch to doing this in two steps (create and save the specification, then create and save the related revision) - however, my client does not want this, so it is not an option.

I'm really hoping that I'm missing something in the framework and that there's an easier way around this. Any ideas?

Edit:

These tables are both part of a larger system, so the schema is complex. A simplified version of each with irrelevant sections removed and renamed as appropriate:

Specifications:
  connection: doctrine
  tableName: specifications
  columns:
    specification_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    specification_name:
      type: string(10)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    Revisions:
      local: specification_id
      foreign: specification_id
      type: many

Revisions:
  connection: doctrine
  tableName: revisions
  columns:
    revision_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    specification_id:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    revision_is_current:
      type: integer(1)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    revision_effective_date:
      type: date(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    revision_name:
      type: string(20)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    revision_deactivated_date:
      type: date(25)
      fixed: false
      unsigned: false
      primary: false
      notnull: false
      autoincrement: false
    revision_filename:
      type: string(40)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    Specifications:
      local: specification_id
      foreign: specification_id
      type: one

RevisionsForm is embedded into SpecificationsForm via this command in SpecificationsForm.class.php:

$newRevision = new RevisionsForm();    
$this->embedForm('Revision', $newRevision;

I can easily make the whole thing work when the specification_id already exists, but I don't see a way to do it until $form->save() is called for the parent SpecificationsForm. I feel like I'm missing something very obvious, but the symfony documentation is very sparse on embedded forms.

If no other solution presents itself, Versionable looks like it will do the job (albeit with a lot of repeated data).

Frostbeard
  • 77
  • 6

1 Answers1

0

I would make life easy on myself and use the Versionable behavior.

Specification:
  actAs:
    Versionable: 
      versionColumn: version
      className: %CLASS%Version
      auditLog: true
  columns:
    #your columns here

That said this should work out of the box if you are using SpecificationForm as the main form and embedding RevisionForm into it. Please post your code for the embedding process, and your schema definitions.

prodigitalson
  • 60,050
  • 10
  • 100
  • 114