Go to content Go to navigation Go to search

People

Businesses

Stepping 24 September 2006

So I needed to save multiple instances of the same model. I thought I’d seen this somewhere else recently but I couldn’t find anyone who had all the information.

My Model has a $hasMany as follows:


var $hasMany = array(
'Step' => array(
'className' => 'Step',
'order' => 'Step.ordernum ASC',
'dependent' => 'true'
)
);

We’ll call the model the above code appears in “Staircase”. This means that my staircase has many steps. Well, when I create a new staircase, I have a form that allows me to create the staircase and then put in step after step (as many as are needed).

So first, the $html->input() method is broken. The first specifier works only with singular input like this: $html->input('Staircase/name'). Now what happens when I get to the steps? I want to be able to do this:


for($i=1; $i<20; $i++)
{
	$html->input($i.'/Step/text');
}

Well, that didn’t work at all. It would name the field wrong and do all sorts of terrible stuff with ids and attributes. So I asked around and PhpNut_ told me that I have to do it by hand. So here’s what I have:


for($i=1; $i<30; $i++)
{
echo '<input type=text name="['.$i.'][Step][text]' id="step'.$i.'text" />';
}

Now I’ve got multiple inputs that work (I’m using CSS to hide all but three so that the page will essentially handle up to 30 (or however many) steps it can be input but it defaults to showing three to input. Really, who wants to climb a staircase with 30 steps compared to three steps?

Now for the saving function. My form is posting to a new page that uses the cakePHP validator, then it tries to save all the objects. Well, if you just do this:


foreach($data['Steps'] as $Step)
{
$this->Staircase->Step->save($Step);
}

You will only get one new step added. I will add the last one. Now, what it was actually doing was adding each one. It adds one, moves to the next and then, because it’s an object, it uses that same object instantiation and just overwrites the last step you just saved. Thus, you end up with only the last step actually saved to the database.

It’s easier to solve than this, though.


foreach($data['Steps'] as $Step)
{
$this->Staircase->Step->create();
$this->Staircase->Step->save($Step);
}

What I’m doing here is iterating through the array still but every time I hit a new node, I just create a new step on the staircase before saving a step’s data.

Think of it this way:

You can’t write on a piece of paper until you’ve taken one out. Cake will take the first piece of paper out of the drawer for you but you need to take out more paper if you want to write more.

Sphere: Related Content

Leave a Comment