2015-10-13 16 views
8

Abbiamo creato una raccolta utilizzando i moduli propel e Symfony2. Possiamo salvare il modulo senza problemi e possiamo aggiungere una seconda opzione utilizzando la raccolta. Se poi ci salviamo e poi tenta di aggiungere un 3 ° collezione otteniamo il seguente errore:Offset undefined Collection Symfony2 + Propel: 2

Notice: Undefined offset: 2 

Stack Trace

in src/app/MyBundle/Model/om/BaseLabelsLabelsLinesMapsQuery.php at line 241 

$cton0 = $this->getNewCriterion(LabelsLabelsLinesMapsPeer::ID, $key[0], Criteria::EQUAL); 
      $cton1 = $this->getNewCriterion(LabelsLabelsLinesMapsPeer::LABEL_ID, $key[1], Criteria::EQUAL); 
      $cton0->addAnd($cton1); 
      $cton2 = $this->getNewCriterion(LabelsLabelsLinesMapsPeer::LABEL_LINES_ID, $key[2], Criteria::EQUAL); 
      $cton0->addAnd($cton2); 
      $this->addOr($cton0); 
     } 

Ho inviato il relativo codice di seguito, tuttavia, come si è tranquillo un sostanziale quantità di codice. Ci stavamo chiedendo se qualcuno avesse avuto questo stesso problema.

Ho inviato un bug report con un diverso bit di codice che ha creato lo stesso errore ma non ho ricevuto risposta. Il bug report è here.

Si tratta di un frammento dello schema relativo:

<table name="labels_labels_lines_maps" isCrossRef="true"> 
    <column name="id" 
      type="integer" 
      required="true" 
      autoIncrement="true" 
      primaryKey="true"/> 
    <column name="label_id" 
      type="integer" 
      primaryKey="true"/> 
    <column name="label_lines_id" 
      type="integer" 
      primaryKey="true"/> 
    <foreign-key foreignTable="labels" onDelete="cascade"> 
     <reference local="label_id" foreign="id"/> 
    </foreign-key> 
    <foreign-key foreignTable="labels_lines" onDelete="cascade"> 
     <reference local="label_lines_id" foreign="id"/> 
    </foreign-key> 
    <vendor type="mysql"> 
     <parameter name="Engine" value="InnoDB" /> 
     <parameter name="Charset" value="utf8" /> 
    </vendor> 
</table> 

<table name="labels_lines"> 
    <column name="id" 
      type="integer" 
      required="true" 
      autoIncrement="true" 
      primaryKey="true"/> 
    <column name="placeholder_text" 
      type="varchar" 
      size="150"/> 
    <column name="font_id" 
      type="integer"/> 
    <column name="font_size" 
      type="integer"/> 
    <column name="x_axis" 
      type="integer"/> 
    <column name="y_axis" 
      type="integer"/> 
    <column name="width" 
      type="integer"/>  
    <column name="height" 
      type="integer"/>  
    <column name="colour" 
      type="varchar" 
      size="20"/>   
    <column name="angle" 
      type="integer"/> 
    <column name="is_volume" 
      type="boolean"/> 
    <column name="is_percentage" 
      type="boolean"/> 
    <column name="is_productof" 
      type="boolean"/> 
    <column name="is_type" 
      type="boolean"/> 
    <column name="is_occasion" 
      type="boolean"/>   
    <foreign-key foreignTable="font" onDelete="cascade"> 
     <reference local="font_id" foreign="id"/> 
    </foreign-key> 
    <vendor type="mysql"> 
     <parameter name="Engine" value="InnoDB" /> 
     <parameter name="Charset" value="utf8" /> 
    </vendor> 
</table> 

<table name="occasion"> 
    <column name="id" 
      type="integer" 
      required="true" 
      autoIncrement="true" 
      primaryKey="true"/> 
    <column name="occasion" 
      type="varchar" 
      size="200"/> 

    <vendor type="mysql"> 
     <parameter name="Engine" value="InnoDB" /> 
     <parameter name="Charset" value="utf8" /> 
    </vendor> 
</table> 

<table name="font"> 
    <column name="id" 
      type="integer" 
      required="true" 
      autoIncrement="true" 
      primaryKey="true"/> 
    <column name="name" 
      type="varchar" 
      size="100"/> 
    <column name="location" 
      size="300"/> 
    <vendor type="mysql"> 
     <parameter name="Engine" value="InnoDB" /> 
     <parameter name="Charset" value="utf8" /> 
    </vendor> 
</table> 

Sotto è la vista (senza styling):

{{ form_start(form) }} 
{{ form_row(form._token) }} 
<ul class="labelsliness list-group" data-prototype="{{ form_widget(form.labelsliness.vars.prototype)|e }}"> 
        {% for lines in form.labelsliness %} 
         <li>{{ form(lines) }}</li> 
        {% endfor %} 
       </ul> 

       {{ form_row(form.save) }} 

{{ form_end(form) }} 

<script> 
        var $collectionHolder; 

        var $addLinesLink = $('<button class="add_line_link btn btn-primary">Add a line</button>'); 
        var $newLinkLi = $('<li></li>').append($addLinesLink); 

        $(document).ready(function(){ 
         $collectionHolder = $('ul.labelsliness'); 

         $collectionHolder.append($newLinkLi); 

         $collectionHolder.data('index', $collectionHolder.find(':input').length); 

         $addLinesLink.on('click', function(e) { 
          e.preventDefault(); 

          addLineForm($collectionHolder, $newLinkLi); 
         }); 
        }); 

        function addLineForm($collectionHolder, $newLinkLi) { 
         var prototype = $collectionHolder.data('prototype'); 

         var index = $collectionHolder.data('index'); 

         var newForm = prototype.replace('/__name__/g', index); 

         $collectionHolder.data('index', index + 1); 

         var $newFormLi = $('<li></li>').append(newForm); 

         $newFormLi.append('<button class="remove-line btn btn-danger">Remove</button>'); 

         $newLinkLi.before($newFormLi); 

         $('.remove-line').click(function(e){ 
          e.preventDefault(); 

          $(this).parent().remove(); 

          return false; 
         }); 
        } 
       </script> 

Il modulo che gestisce questo:

public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
       ->add("labelsliness", "collection", array(
        "type" => new LabelsLinesType(), 
        "allow_add" => true, 
        "allow_delete" => true, 
        "by_reference" => false 
       )) 
       ->add("save", "submit"); 
    } 

    public function configureOptions(OptionsResolver $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'AJSharp\EPCBundle\Model\Labels', 
     )); 
    } 

    public function getName() 
    { 
     return "label_form"; 
    } 

Infine, di seguito è il controller.

public function editAction(Request $request, $id = null) 
    { 

     $labels = LabelsQuery::create()->findPk($id); 

     $form = $this->createForm(new EditLabelType(), $labels); 

     $form->handleRequest($request); 

     if ($form->isValid()) { 

      $labels->save(); 
      return $this->redirect($this->generateUrl("_admin_labels")); 
     } 

     return $this->render("AppLabelBundle:Admin:edit.html.twig", array("form" => $form->createView())); 
    } 
+0

e il codice 'BaseLabelsLabelsLinesMapsQuery.php' è? – Alex

+0

@Alex poiché ci sono poche righe nello script che ho copiato in pastebin. http://pastebin.com/WXgfN7yf. Si prega di notare che questo codice è completamente generato da Propel. –

risposta

1

lo schema è un po 'di confusione per me. Questo bit di seguito include tre chiavi primarie con due di loro come una chiave esterna e uno di loro come un identificatore univoco per la riga:

<table name="labels_labels_lines_maps" isCrossRef="true"> 
    <column name="id" 
      type="integer" 
      required="true" 
      autoIncrement="true" 
      primaryKey="true"/> 
    <column name="label_id" 
      type="integer" 
      primaryKey="true"/> 
    <column name="label_lines_id" 
      type="integer" 
      primaryKey="true"/> 
    <foreign-key foreignTable="labels" onDelete="cascade"> 
     <reference local="label_id" foreign="id"/> 
    </foreign-key> 
    <foreign-key foreignTable="labels_lines" onDelete="cascade"> 
     <reference local="label_lines_id" foreign="id"/> 
    </foreign-key> 
    <vendor type="mysql"> 
     <parameter name="Engine" value="InnoDB" /> 
     <parameter name="Charset" value="utf8" /> 
    </vendor> 
</table> 

ho il sospetto un sacco di guai può andare via se si sceglie una cosa e insisti. Rimuovere id e fare in modo che la chiave composita primaria rappresenti due tabelle esterne, che è perfettamente valida oppure modificare i limiti PRIMARY KEY a UNIQUE su ciascuna chiave esterna, lasciando la chiave primaria come id. Questo è anche perfettamente valido.Alla fine la tua decisione sarà basata sui tuoi requisiti di progettazione.

Un'altra nota: è possibile o meno voler eseguire un heavyIndexing, in particolare se si fa riferimento a singole colonne nella chiave primaria. Una chiave primaria composta crea un indice contro tutte e tre le colonne, non ciascuna individualmente. Questo potrebbe o non potrebbe essere importante nel tuo progetto, ma ho pensato che valesse la pena segnalarlo.

+0

Ciao, grazie per la menzione di heavyIndexing. In realtà non l'ho mai usato quindi darò un'occhiata a questo. Inizialmente stavo seguendo il seguente schema (propelorm.org/documentation/cookbook/symfony2/mastering-symfony2-forms-with-propel.html#many-to-many-relations) Tuttavia, come hai sottolineato. L'ID non è in realtà nello schema molti a molti. Credo che questo potrebbe essere la causa principale del problema. Daro 'un'occhiata e torno da te. –

0

Io non sono sicuro al 100% su questo, ma sono abbastanza certo che sia perché questa linea:

$labels = LabelsQuery::create()->findPk($id); 

noterete nel metodo findPkSimple nella classe BaseQuery è mi aspetto che la variabile sia una matrice con 3 valori (indici 0, 1, 2)

Il motivo per cui non sono sicuro è che non so se $ id è solo un valore o un array come la definizione della funzione non hai restrizioni sul tipo. (la tua funzione editAction)

Penso che, poiché hai tre chiavi primarie, la classe che viene generata si aspetta che tu abbia tre singoli valori durante la ricerca per chiave primaria.

Potrebbe essere più efficace se si dispone di una sola chiave primaria, e poi un indice univoco su questi tre colonne a garantire l'unicità (se è quello che si sta andando per)

+0

Giusto per chiarire che $ id è un singolo id e non un array. Per quanto riguarda l'avere una chiave primaria. Da qui ho preso le seguenti informazioni (propelorm.org/documentation/cookbook/symfony2/mastering-symfony2-forms-with-propel.html#many-to-many-relations) che mostra le molteplici chiavi primarie. Tuttavia, l'id non è in realtà su questa mappa nell'esempio. –

+0

Penso che quell'esempio potrebbe essere scaduto o semplicemente sbagliato. Nel loro esempio hanno una chiave primaria che è anche una chiave straniera. – William