2

I have a parent/child self association table where when the id = parent_id, that id is it's own parent. However I'm having trouble saving data into my table from the add action/view

From add.ctp view - when adding a new record, I select a parent_id from the drop down box and enter a name.

<?php
    echo $this->Form->input('parent_id', array('empty' => 'No Parent'));
    echo $this->Form->input('name');
?>

If user selects "No Parent" this means I would like the parent_id = id where id is the unique ID automatically created in DB at time it is saved.

This is what is passed into $this->request->data when 'No Parent' is selected.

array(
    'Item' => array(
        'parent_id' => '',
        'name' => 'testname'
    )
)

I have tried to set the parent_id = id in the beforeSave but since id does not yet exist, there is nothing to assign parent_id to. I have also tried calling the "parent" model save first and saveAll in the controller but those don't work either.

Controller

public function add() {
    if ($this->request->is('post')) {
        $this->Item->create();

        //have tried calling parent model in self association first but 
        //if ($this->Item->ParentItem->save($this->request->data)) {
        if ($this->Item->saveAll($this->request->data)) {

            $this->Session->setFlash(__('The item has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The item could not be saved. Please, try again.'));
        }
    }

Item.php / Model relationship

public $belongsTo = array(
  'ParentItem' => array(
  'className' => 'Item',
  'foreignKey' => 'parent_id',
  'conditions' => '',
  'fields' => '',
  'order' => ''
  )
);

public $hasMany = array(
  'ChildItem' => array(
  'className' => 'Item',
  'foreignKey' => 'parent_id',
  'dependent' => false,
  'conditions' => '',
  'fields' => '',
  'order' => '',
  ) 
);

How can I take an ID that is just created/saved and save that to another field, in this case parent_id?

UPDATE: I have been working on this some more and I have used getInsertId() to get the last inserted Id and I am trying to save that into the parent_id, but there is something that prevents this. I have removed all model validation to make sure it wasn't that. But is there something in Cake (or my association setup) that does not allow parent_id = id (i.e. a row is it's own parent?

This is the latest code in my add action... This saves a row to the DB, but w/o a parent_id. I then try to edit using the add action and set the parent_id = id, but even the edit wont allow a save.

public function add() {
    if ($this->request->is('post')) {
        $this->Item->create();
        if ($this->Item->save($this->request->data)) {
            $last_id = $this->Item->getInsertId();
            $this->Item->saveField('parent_id', $last_id);
            $this->Session->setFlash(__('The item has been saved'));
            $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The item could not be saved. Please, try again.'));
        }
    }

I have also tried calling $this->Item->ParentItem->save(), saveAll, 'deep' => true, but still nothing is allowing me to update the parent_id column. A row ge

Thanks in advance

1
  • upvote for a perfect question with detailed explanation, it help me resolve my single db table category/parent_id issue I was searching for.. Commented Jul 29, 2013 at 10:18

2 Answers 2

1

In Your model of association You can set foregin_key to parent_id, and will be automatic filled

2
  • Thanks for your reply. I do have a foreign_key setup in my model, this is why it is puzzling me... I have edited my question to show the model relationship setup
    – mk97
    Commented Mar 21, 2013 at 13:25
  • after playing around some more it almost seems like I need to perform a save on the item (this auto generates the primary id key when saved) and then perform an edit on that newly created item to insert the id into parent_id... however that seems like what needs to be done, but I suspect there's a more straight forward way to do this...
    – mk97
    Commented Mar 21, 2013 at 15:42
0

So the problem I was having... trying to set a parent_id = id (making id it's own parent basically) in a self join model is due to this piece of code in my Model file

public $actsAs = array('Tree');

After reading through the Tree Behavior again, I realized that $this->Model->save (or saveField) does not really work well with Tree structures and updating parent IDs. Should use the behaviors functions instead form my understanding. Also the TreeBehavior expects some parent_ids to be null (at least top level parent_ids), so if I were to leave this as a tree, the ids with a null parent_id would be considered the parent.

http://book.cakephp.org/2.0/en/core-libraries/behaviors/tree.html

"The parent field must be able to have a NULL value! It might seem to work if you just give the top elements a parent value of zero, but reordering the tree (and possible other operations) will fail."

So I need to decide if I want to use tree behavior or have simple parent/child relationship without using Tree... think I will do the later as I don't have a need for multilevel tree, just a parent and one level of children.

Thanks for replies.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.