Eugen
Eugen

Reputation: 1386

CakePHP 2.1 : HABTM saveAssociated and keep exists data

I have a little problem with saveAssociated and exists entries :(

Models:

Ingredient.php

<?php

class Ingredient extends AppModel {

    public $name = 'Ingredient';
    public $hasMany = array('IngredientsRecipes');

    public $hasAndBelongsToMany = array(
        'Recipe' =>
            array(
                'className'              => 'Recipe',
                'joinTable'              => 'ingredients_recipes',
                'foreignKey'             => 'ingredient_id',
                'associationForeignKey'  => 'recipe_id',
                'unique'                 => 'keepExisting',
                'conditions'             => '',
                'fields'                 => '',
                'order'                  => '',
                'limit'                  => '',
                'offset'                 => '',
                'finderQuery'            => '',
                'deleteQuery'            => '',
                'insertQuery'            => ''
            )
    );
 }

Recipe.php

<?php
class Recipe extends AppModel {
    public $name = 'Recipe';
    public $hasMany = array('IngredientsRecipes');
    public $hasAndBelongsToMany = array(
        'Ingredient' =>
            array(
                'className'              => 'Ingredient',
                'joinTable'              => 'ingredients_recipes',
                'foreignKey'             => 'recipe_id',
                'associationForeignKey'  => 'ingredient_id',
                'unique'                 => 'keepExisting',
                'conditions'             => '',
                'fields'                 => '',
                'order'                  => '',
                'limit'                  => '',
                'offset'                 => '',
                'finderQuery'            => '',
                'deleteQuery'            => '',
                'insertQuery'            => ''
            )
    );
}

IngredientRecipe.php

<?php
class IngredientRecipe extends AppModel {
    public $name = 'IngredientsRecipes';
    public $belongsTo = array('Ingredient', 'Recipe');
}

Views:

View/IngredientsRecipes/add.ctp

<?php echo $this->Form->create('IngredientRecipe'); ?>
    <?php echo $this->Form->input('Ingredient.ingredient', array('type' => 'text', 'label' => 'Ingredient')); ?>
    <?php echo $this->Form->input('Recipe.recipe', array('type' => 'text', 'label' => 'Recipe')); ?>
    <button type="submit">Save</button>
<?php echo $this->Form->end(); ?>

Contollers:

IngredientRecipeController.php

<?php
class IngredientRecipeController extends AppController {

public function add() {
    if ($this->request->is('post')) {
     if(!empty($this->request->data)) {
       $ingredients_comma_separated = explode(',', $this->request->data['Ingredient']['ingredient']);
       $recipes_comma_separated = explode(',', $this->request->data['Recipe']['recipe']);
       $recipes = array();
         foreach($ingredients_comma_separated as $ingredient){
         $recipes['Ingredient']['ingredient'] = trim($ingredient);
         foreach($recipes_comma_separated as $recipe){
         $recipes['Recipe']['recipe'] = trim($recipe);
        if ($this->IngredientRecipe->saveAssociated($recipes, array('deep' => true, 'validate' => 'first'))) {
            $this->Session->setFlash('Saved.');
            }
          }
        }
      } 
    }
  }
}

MySQL Tables:

CREATE TABLE IF NOT EXISTS `ingredients` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ingredient` varchar(250) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ingredient` (`ingredient`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `ingredients_recipes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ingredient_id` int(11) NOT NULL,
  `recipe_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

CREATE TABLE IF NOT EXISTS `recipes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `recipe` varchar(250) NOT NULL,
  `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `recipe` (`recipe`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

My Question:

How i can keep exists data in recipes & ingredients fields and continue saving associated data in ingredients_recipes field ?

Upvotes: 0

Views: 2902

Answers (3)

sanu
sanu

Reputation: 1068

make unique=false in both Recipe and Ingredient Model and from Recipe controller do

$this->Recipe->saveAll($this->request->data)

I think this will work

Upvotes: 0

pbond
pbond

Reputation: 1927

'unique' => 'keepExisting', Isn't meant for this. What it does, is keeping the existing information of additional rows in the join table, but it still acts the same as 'unique' => true.

See: http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html#ref-habtm-arrays

What you need to do is set it to false.

Upvotes: 3

shuaiyuancn
shuaiyuancn

Reputation: 2794

Since the recipe and ingredient records already exist, you should be able to get their id. Then when saving data, you simply supply the id to save the new relation, like

dataArray = array(
    'recipe'=>array('id'=>$recipeId),
    'ingredient'=>array('id'=>$ingredientId)
);

In this way records in recipe and ingredient tables would not be modified or duplicated.

If your inputs from form is text instead selections like a drop-down-list, you probably need to manually find the id before saving the relation.

Upvotes: 1

Related Questions