Symfony2 + Propel Collection未定义偏移量:2

时间:2015-10-13 14:49:53

标签: php symfony propel

我们使用propel和Symfony2表单创建了一个集合。我们可以毫无问题地保存表单,我们可以使用该集合添加第二个选项。如果我们然后保存然后尝试添加第3个集合,我们会收到以下错误:

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

2 个答案:

答案 0 :(得分: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更改为UNIQUE每个外键的约束,留下您的主键为id。这也完全有效。最终,您的决定将基于您的设计要求。

另一个注意事项:您可能会或可能不想heavyIndexing,尤其是在您引用主键中的各个列时。复合主键为所有三列创建索引,而不是单独创建每个列。这在你的项目中可能重要,也可能不重要,但我认为值得指出。

答案 1 :(得分:0)

我对此并不是100%肯定,但我相当肯定是因为这一行:

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

您会注意到BaseQuery类中的方法findPkSimple,它期望变量键是一个包含3个值的数组(索引0,1,2)

我不确定的原因是我不知道$ id是一个值还是一个数组,因为你所拥有的函数定义并不限制类型。 (你的editAction函数)

我认为,因为你有三个主键,所生成的类要求你在按主键搜索时有三个单独的值。

如果你只有一个主键,然后在这三个列上有一个唯一索引以确保唯一性(如果这就是你想要的那个),它可能会更有效