I have one-to-many relationship between 2 tables (content, images).
Below is a part from schema.yml:

Content:
  columns:
    id: { type: integer(4), primary: true, autoincrement: true }
    title: { type: string(255), notnull: false }
    fullcontent: { type: string(), notnull: false }
    section: { type: integer(4), notnull: true } # this is foreign key
from another table
# others ...

Image:
  columns:
    id: { type: integer(4), primary: true, autoincrement: true }
    content: { type: integer(4), notnull: true }
    file: { type: string(255), notnull: true }
    author: { type: string(255), notnull: false }
# others ...
  relations:
    Content:
      local: content
      foreign: id
      type: one
      alias: Content
      foreignAlias: Images
      foreignType: many
      onDelete: CASCADE

Generated model looks like this:

class BaseContent extends sfDoctrineRecord {
  //...
  public function setUp()
    {
        parent::setUp();
        //...
        $this->hasMany('Image as Images, array(
             'local' => 'id',
             'foreign' => 'content'));
    }
}

class BaseImage extends sfDoctrineRecord {
  //...
    public function setUp()
    {
        parent::setUp();
        $this->hasOne('Content', array(
             'local' => 'content',
             'foreign' => 'id',
             'onDelete' => 'cascade'));
    }
}

I have generated app with module 'image' for Image model.

Normally, generated form to insert/edit image record contains
sfWidgetFormDoctrineChoice to display <select /> tag for the 'content'
field. But I don't want it like this because I have a lot of Content
records in database and rendering the widget is always out of max
execution time form php script. So I decided to pass content id as a
parameter to the image form. This is what I put in actions.class.php
in image module:

class imageActions extends sfActions
{
  //...
  public function executeNew(sfWebRequest $request)
  {
      $this->forward404Unless($request->getParameter('content'));
      $this->forward404Unless($content = Doctrine::getTable('Content')-
>find(array($request->getParameter('content'))));
      $image = new Image();
      $image->setContent($content);
      $this->form = new ImageForm($image);
  }
  //...
}

I also modified form class:

class ImageForm extends BaseImageForm
{
  public function configure()
  {
    $this->setWidget('content',
      new sfWidgetFormInputHidden(array('default' => $this-
>getObject()->getContent()->getId()))
    );
    //...
  }
}

Now I run my webpage to display new image form with content id as a
parameter (frontend_dev.php/image/new/content/123456). The form
displays as expected. I see <input hidden="image[content]"
value="123456" /> in generated html. So I fill in the form and click
'Save' and I'm getting error like this:

SQLSTATE[HY000]: General error: 1364 Field 'section' doesn't have a
default value

When I read the stack trace I can see that symfony/doctrine is trying
to insert new record into the Content table while inserting new record
into the Image table. This is done by Doctrine_Connection_UnitOfWork-
>saveGraph(object('Image')) which calls Doctrine_Connection_UnitOfWork-
>saveRelatedLocalKeys(object('Image')) which then calls save() on
Content object. But I only wanted to insert the image record, and the
associated content record already exists in the database. What should
I do to have such a functionality?

Of course, I could create Content form and embed Image form into it
but this is not what I want because the Content form is already quite
complicated and I don't want to make it even more complicated.

So what code should I provide to avoid the insertion of Content record
while saving new Image record?

Another problem arises if I want to have a text description of the
Content record while filling in the Image form.
I created another widget in the image form:

class ImageForm extends BaseImageForm
{
  public function configure()
  {
    $this->setWidget('content',
      new sfWidgetFormInputHidden(array('default' => $this-
>getObject()->getContent()->getId()))
    );
    $this->setWidget('contenttxt',
      new sfWidgetFormPlain(array('value' => $this->getObject()-
>getContent()))
    );
    //...
  }
}

The second widget displays plain text on the form describing to what
content record I'm trying to insert an image. When symfony renders the
form for the first time the widget displays normally, but when it
needs to render the form again because of validation errors, the
second widget cannot find it's data. getContent() method returns empty
new Content model instance and it's __toString() method throws an
exception because it tries to return the content title (return $this-
>getTitle()) which returns null instead of string. So data binding
after the form submission is doing something wrong and I don't now
where to find the source of this problem.

I googled many pages about symfony and doctrine, made many test runs
and found no solution so help me, please.

Kind regards,
Michal

-- 
If you want to report a vulnerability issue on symfony, please send it to 
security at symfony-project.com

You received this message because you are subscribed to the Google
Groups "symfony users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/symfony-users?hl=en

Reply via email to