1

I have setup 3 tables in symfony:

A flipbook table, A Skills table, and a relations table, to connect each skill id with each flipbook id.

WHen I built the model, symfony constructed everything correctly, and by default gave a drop-down menu for the skills, which had all skills from the skills table as options. You can select an option and it creates the appropriate relationships.

This is working (sort of). When you submit the form, it does not add the skill_id to the record. It just adds the auto-increment id to the skills relations table and neither the flipbook_id or skill_id. Aaaaaand, if you click more than one checkbox, you get this nice message:

invalid parameter number number of bound variables does not match number of tokens

Whaaaat does that mean? This has got to be a schema issue eh?

How about some code? yes.please.

Schema:

Flipbook:
  tableName: flipbook
  inheritance:
    extends: SvaGeneric
    type: concrete
  columns:
    title: { type: string(255) }
    career_associations: { type: clob }
    skills: { type: string(255) }
    skills_associations: { type: clob }
    program: { type: string(255) }
    program_associations: { type: clob }
    draft_id: { type: integer(10) }

FlipbookSkills:
  tableName: flipbook_skills
  columns:
    title: { type: string(255) }
  relations:
    Flipbook:
      foreignAlias: flipbook_skills
      alias: skills
      local: title
      onDelete: SET NULL   

FlipbookSkillRelations:
  tableName: flipbook_skill_relations
  actAs:
    SoftDelete: ~
  options:
  columns:
    flipbook_id: { type: integer(10), notnull: false }
    skill_id: { type: integer(10), notnull: false }
  relations:
    Flipbook:
      foreignAlias: flipbook_skills_flipbook
      alias: flipbook
      local: flipbook_id
      onDelete: CASCADE
    FlipbookSkills:
      foreignAlias: flipbook_skills_skills
      alias: flipbookskills
      local: skill_id
      onDelete: CASCADE

FlipbookSkillsRelationsForm.class.php:

$this->widgetSchema['flipbook_id'] = new sfWidgetFormInputText(array(), array('class' => 'text size-500'));

$this->widgetSchema['skill_id'] = new sfWidgetFormSelectCheckbox(array('choices' => "**WHAT GOES HERE??**"), array('class' => 'text size-500'));


$useFields = array(
  'flipbook_id',
  'skill_id',
);

$this->useFields($useFields);

Let me know if I should provide further code or explanation.

Here is the FlipbookSkillsTable.class generated in the model:

<?php

/**
 * FlipbookSkillsTable
 * 
 * This class has been auto-generated by the Doctrine ORM Framework
 */
class FlipbookSkillsTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object FlipbookSkillsTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('FlipbookSkills');
    }

    public function retrieveForFilter()
    {
      $res = $this->createQuery('s')
        ->select('s.id, s.name')
        ->orderBy('s.name ASC')
        ->execute(array(), Doctrine_Core::HYDRATE_NONE);

      // if you want an empty line
      $rets = array('' => '');
      foreach ($res as $ret)
      {
        $rets[$ret[0]] = $ret[1];
      }

      return $rets;
    }

    public function getAllFlipbookSkills() {
        $allSkills = Doctrine_Query::create()
            ->from('FlipbookSkills')
            ->orderBy('title ASC')
            ->execute();
    return $allSkills;
    }
}

UPDATE

I believe the issue is it is trying to bind the multiple values in the same record. It should make a new record for each skill chosen, like this:

id    flipbook_id    skill_id
1          2            1
2          2            2
3          2            3

SO I still don't have the schema nailed down correctly, otherwise Doctrine would know how to handle the data correct? Should I explicitly put one to many relationship?

Also, when submitted, it is only adding the flipbook_id value to the record. The skill_id record is 0

FLipbookRelationsForm:

class FlipbookSkillRelationsForm extends BaseFlipbookSkillRelationsForm
{
  public function configure()
  {

    $this->widgetSchema['skill_id'] = 
       new sfWidgetFormDoctrineChoice(array('model' => 
           $this->getRelatedModelName('flipbookskills'), 
            'expanded' => true, 'multiple' => true, 'add_empty' => false));

    $useFields = array(
            'flipbook_id',
            'skill_id',
        );

    $this->useFields($useFields);
  }
}

2 Answers 2

1

Multiple issues (maybe this post can help: Embedded forms in symfony 1.4 not saving propperly)

Your n-m relations doesn't look well defined. Your entities should looks like:

FlipbookSkill:
  tableName: flipbook_skill
  columns:
    title: { type: string(255) }
  relations:
    Flipbooks:
      class: Flipbook
      refClass: FlipbookSkillRelation
      local: skill_id
      foreign: flipbook_id
/* Not foreignAlias and onDelete behaviour defined */

Flipbook:
  tableName: flipbook
  inheritance:
    extends: SvaGeneric
    type: concrete
  columns:
    title: { type: string(255) }
    career_associations: { type: clob }
    skills: { type: string(255) } # why this????
    skills_associations: { type: clob }  # why this????
    program: { type: string(255) }
    program_associations: { type: clob }
    draft_id: { type: integer(10) }
  relations:
    Skills:
      class: FlipbookSkill
      refClass: FlipbookSkillRelation
      local: flipbook_id
      foreign: skill_id

FlipbookSkillRelation:
  tableName: flipbook_skill_relation
  actAs:
    SoftDelete: ~
  options:
  columns:
    flipbook_id: { type: integer(10), notnull: false }
    skill_id: { type: integer(10), notnull: false }
  relations:
    Flipbook:
      foreignAlias: FlipbookSkills
      local: flipbook_id
      foreign: id
      onDelete: CASCADE
    FlipbookSkill:
      foreignAlias: FlipbookSkills
      local: skill_id
      foreign: id
      onDelete: CASCADE

Then, you methods/join allowed are:

$flipbookObject->getSkills(); Because flipbook entity n-m relation name "Skills", wich returns a FlipbookSkill DoctrineCollection. Or in query ('f.innerJoin Skills s')

$flipbookObject->getFlipbookSkills(); Because flipbookSkillRelation 1-n foreignAlias name, but probably you will never use this (because you don't really care about relations inself, instead you care about related skills). ... etc

If you have a well defined schema.yml, then your forms should work properly.

Plus: why are you using and text input widget for an id field (flipbook_id) ???? And why are you using a sfWidgetFormSelectCheckbox if you are working with doctrine entities? You should use sfWidgetFormDoctrineChoice like the BaseEntity defines.

I hope this can help you.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the help with the schema. It has been updated, but I am still getting the error. Also to answer some of the last questions: Text Input for flipbook id was temporary to see if the value was getting loaded. It is set to hidden. I am using sfWidgetFormSelectCheckbox to get the skills into a checkbox html element. If I use sfWidgetFormDoctrineChoice, it puts them into a dropdown. I want the user to be able to associate multiple skills to one flipbook. I cannot get sfWidgetFormDoctrineChoiceMany to work properly either. Getting a Class not found error.
Aaaaah...set multiple to true and it will make the radio boxes.
Still getting the error though: Invalid parameter number: number of bound variables does not match number of tokens
I guess that the FlipbookSkillRelationsForm (as any relation entity form) should never be used. I was asking about the FlipbookForm. In your action code, you should have something like $this->form = new XXXX(). I need the code of that XXXX class (I guess that it is FlipbookForm)
0

Where are your validators ? Symfony forms don't work properly with missing validators or inappropriate ones. If your validator accept 1-1 relationship, and you send multiple values, it won't work.

Try this :

$this->validatorSchema->setOption('allow_extra_fields' , true);
$this->validatorSchema->setOption('filter_extra_fields' , false);

If your error disappear, then you have a problem with validators. Otherwise you can try to use a the sfEmbedded forms, you render an sfForm, and add multiple time your FlipbooSkillForm with selects. If i remeber well there is some tutorials showing how to add them in js.

http://nacho-martin.com/dynamic-embedded-forms-in-symfony

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.