2015-10-13 53 views
8

我們使用propel和Symfony2形式創建了一個集合。我們可以毫無問題地保存表單,並且可以使用該集合添加第二個選項。如果我們再保存,然後嘗試添加第三個集合中,我們得到以下錯誤:Symfony2 + Propel Collection未定義偏移量:2

Notice: Undefined offset: 2 

堆棧跟蹤

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

我已經發布了以下相關的代碼,但是因爲有安靜的大幅代碼量。我們想知道是否有人遇到同樣的問題。

我發送了一個錯誤報告,其中有一個代碼創建了相同的錯誤,但我沒有收到任何回覆。錯誤報告是here

這是相關的架構的一個片段:

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

下面是視圖(沒有任何造型):

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

處理此問題的表單:

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

最後,下面是控制器。

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

和你的'BaseLabelsLabelsLinesMapsQuery.php'代碼是? – Alex

+0

@Alex,因爲腳本中有幾行我已將其複製到pastebin中。 http://pastebin.com/WXgfN7yf。請注意,此代碼完全由Propel生成。 –

回答

1

你的架構是有點混亂,這可能是更有效我。低於此位包括其中兩個三個主鍵的外鍵,其中一人作爲行的唯一標識符:

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

如果你選擇一件事,我懷疑你的很多麻煩可能消失的和堅持下去。刪除id並讓您的主要組合鍵代表兩個外表,這是完全有效的,或者將您的PRIMARY KEY s更改爲UNIQUE,並將您的主鍵保留爲id。這也是完全有效的。最終,您的決定將基於您的設計要求。

另一個注意事項:您可能會也可能不想要執行heavyIndexing,特別是在引用主鍵中的單個列時。組合主鍵會針對所有三列創建索引,而不是每個列。這在你的項目中可能很重要,但我認爲這值得指出。

+0

嗨,謝謝你提到heavyIndexing。我從來沒有用過它,所以我會看看這個。我原本是在下面的模式(propelorm.org/documentation/cookbook/symfony2/mastering-symfony2-forms-with-propel.html#many-to-many-relations)然而,正如你指出的那樣。 Id實際上並不在多對多的模式中。我相信這可能是問題的根源。我會看看並回到你身邊。 –

0

我對這個不是100%肯定,但我敢肯定這是因爲該行:

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

你會在方法findPkSimple在BaseQuery類注意到它是期望可變密鑰是一個具有3個值的數組(索引0,1,2)

我不確定的原因是我不知道$ id是否只是一個值或數組作爲函數定義你對類型沒有限制。 (您的editAction函數)

我認爲,因爲您有三個主鍵,生成的類期望您在使用主鍵搜索時有三個單獨的值。

如果你只有一個主鍵,然後在這些三列的唯一索引以確保唯一性(如果這就是你要什麼)

+0

只是爲了澄清$ id是一個單一的id而不是一個數組。至於有一個主鍵。我從這裏獲得了以下內容(propelorm.org/documentation/cookbook/symfony2/mastering-symfony2-forms-with-propel.html#many-to-many-relations),它顯示了多個主鍵。但是在這個例子中id實際上並不在這個地圖上。 –

+0

我認爲這個例子可能會過時,或者完全錯誤。在他們的例子中,他們有一個主鍵也是一個外鍵。 – William