0

I have Products mapping to Images via the join table Products_Images

Product Model:

class Product extends AppModel {
    public $hasAndBelongsToMany = array(
        'Image' => array(
            'className' => 'Image',
            'joinTable' => 'products_images',
            'dependent' => true,
            'foreignKey' => 'product_id',
            'associationForeignKey' => 'image_id'
        )
    );    
}

Image Model:

class Image extends AppModel {
    public $hasAndBelongsToMany = array(
        'Product' => array(
            'className' => 'Product',
            'joinTable' => 'products_images',
            'foreignKey' => 'image_id',
            'associationForeignKey' => 'product_id'
        )
    );
}

Action Snippet in Product Controller:

if($this->request->is('post')) {
            if(!empty($this->request->data)) {
                $this->Product->create();
                if($this->Product->save($this->request->data)) {
                    $newProductID = $this->Product->id;

                    foreach($this->request->data['Uploads'] as $image):
                        //Check if image has been uploaded
                        if(!empty($image['name'])) {
                            $ext = substr(strtolower(strrchr($image['name'], '.')), 1); //get the extension
                            $arr_ext = array('jpg', 'jpeg', 'png'); //set allowed extensions

                            //only process if the extension is valid
                            if(in_array($ext, $arr_ext))
                            {
                                //do the actual uploading of the file. First arg is the tmp name, second arg is
                                //where we are putting it
                                move_uploaded_file($image['tmp_name'], './img/uploads/products/' . $image['name']);

                                //prepare the Image for database entry
                                $this->request->data['Image']['name'] = $image['name'];

                                //save image
                                $this->Product->Image->save($this->request->data);
                            }
                        }
                    endforeach;

                    $this->Session->setFlash(
                        'Product has been successfully created.',
                        'default',
                        array('class' => 'alert-success')
                    );
                    return $this->redirect(array('action' => 'view',$newProductID));
                } else {
                    $this->Session->setFlash(
                        'Product has could not be created. Please try again.',
                        'default',
                        array('class' => 'alert-danger')
                    );
                    return $this->redirect(array('action' => 'index'));
                }
            }
        }

This is what the action in the Products controller receives: enter image description here

ISSUE: This adds the Product into the table nicely, it also adds the Image into the table nicely however it creates 4 seamingly random entries in the Products_Images table. It gets the image_id correct, but it inserts 4 random product_ids.

Chronix3
  • 601
  • 2
  • 9
  • 21
  • They aren't random, they're [file upload errors](http://php.net/manual/en/features.file-upload.errors.php) - 4 means no file was uploaded. Looks to me like your associations are fine, it's your upload script that is failing. Check your folder permissions, and assign the result of the `move_uploaded_file()` call to a variable, and if it fails - do something with it, don't just add a blank entry into your database! – scrowler Aug 07 '14 at 21:37
  • @scrowler Judging from his statement that the images are being saved fine, I think it's just that he posted useless test data. The main problem seems that he passes the whole request data array to `Image->save()` without a primary key for `Product`, hence the problems. However I'm not sure what exactly he's trying to save (an actual HABTM association, probably?), and I can't test it right now (not sure whether the association should be saved via the `Product` model instead), so I'm not adding this as an answer. – ndm Aug 07 '14 at 22:19
  • On a side note, `$image['name']` should be validated/sanitized before passing it to `move_uploaded_file()`! – ndm Aug 07 '14 at 22:20

0 Answers0