2

I have an array that is sent to my controller, such as this:

$array = array(
        [0]=>array(
             [id]=>5,
             [position]=>6 
        ),
       [1]=>array(
             [id]=>8,
             [position]=>2 
        )
);

And I need to save the position of each item using its id. What is the best way to do this in cakePHP? I can only imagine looping an update function or pulling the entire database, changing the correct values, then saving the database. Both ideas seem very bodged.

2 Answers 2

4

Ha, Cake magic to the rescue again. You don't have to tell Cake to save it by id. There's a big long amazing way Cake does this, but the short and skinny is -

if your array contains an 'id' key, Cake presumes it is the table primary key and generates an UPDATE statement instead of an INSERT. Looks like this:

UPDATE table as Table SET Table.position = $position WHERE Table.id = $id;

And, Cake knows to iterate for you if you use saveAll() instead of save():

$this->Model->saveAll($array);

If you have any save callbacks in your model, such as beforeSave(), you have to call them manually before calling saveAll() - they only autofire on save(), not saveAll() or updateAll().

You'll want to top your array with the name of your model ($array['Model'][0], $array['Model'][1], etc). If you need to magically saveAll() with multiple models, you top your array with indexed keys, then model names - like $array[0]['Model1'], $array[0]['Model2']) and Cake knows to save / update the associated data for all the models in each index batch.

Cake does ALL the legwork for you:

http://book.cakephp.org/view/1031/Saving-Your-Data - especially the saveAll() entry.

  • Edit - and topping your array with your model name? Cake makes that ridiculously easy, too. Check out Cake's built-in Set library for all your array / object manipulation needs.

http://book.cakephp.org/view/1487/Set

Sign up to request clarification or add additional context in comments.

4 Comments

actually, save all takes int indexed array, not with the model name eg: $this->Article->saveAll($data['Article']); not $this->Article->saveAll($data); where the array is $data['Article'][n]['field]. The array OP pasted in the question is the correct format for saveAll, its documented in the link you pasted but you still got it wrong
@dogmatic69-- actually, I got both exactly right. :) The API is totally clear -> api.cakephp.org/class/model#method-ModelsaveAll - "Record data to save. This can be either a numerically-indexed array (for saving multiple records of the same type), or an array indexed by association name." API entries + redacted code examples pasted from my live app for illustration -> saveAll() 1 record + multiple models works exactly as the API says it does :) Didn't bother pasting an example of saveAll() -> multiple records, 1 model because -> no need, OP's code shows that. :)
@dogmatic69-- It bears mentioning, I answered another closely-related question from the OP shortly before the OP asked this question; the first question included more context and background, and OP's code showed arrays structured a bit differently, etc. I included the extra information about cake's save / saveAll, model callbacks, etc. and examples because the additional background indicated the OP would find heavy-duty Model methods useful / relevant. stackoverflow.com/questions/6285006/…
thanks for your answer, the extra detail was appreciated. I was unsure who to award the correct answer to, since you both linked to the saveAll function which ultimately gave me the solution I was looking for. I gave Dave the correct answer as I though he answered first, but clearly you have the more detailed and useful response.
2

Have you tried CakePHP's saveAll() ? Details here.

1 Comment

I continually underestimate what cake can do. Of course if the data is in the correct format, cake will process it as normal... Seems so simple now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.