Posted on 1/6/08 by Felix Geisendörfer
lets say you have a model called Upload. Your Upload model has some generic fields like this:
However, you would like to store different types of meta information for different kinds of uploads. Examples:
- Quality (if jpg)
- Original Size
- File Count
- Compression Rate
So what are you going to do? Add 13 fields to your uploads table? Probably not. It is time to normalize things:
Ok nothing fancy so far. CakePHP's associations make it easy to deal with it. However, working with this setup can be a little inconvenient at times. Everytime you fetch a set of records from Upload, you will have to manually extract the meta information from the associated UploadField records:
- Upload: id: 1 name: funny.mov type: video/quicktime bytes: 20480 created: 2008-06-01 14:47:23 UploadField: - id: 1 upload_id: 1 key: fps val: 26 - id: 2 upload_id: 1 key: bitrate val: 376
So everytime you want to access your videos bitrate you will have to search your UploadField records for the 'bitrate' key. How annoying. But worry not, Expandable comes to rescue. With the Expandable behavior activated on your Upload model, your resultset will look like this:
- Upload: id: 1 name: funny.mov type: video/quicktime bytes: 20480 created: 2008-06-01 14:47:23 fps: 26 bitrate: 376 UploadField: - id: 1 upload_id: 1 key: fps val: 26 - id: 2 upload_id: 1 key: bitrate val: 376
But it comes even better. Expandable also makes it dead-simple to create / update UploadField records. This is how it works:
'id' => 1,
'fps' => 30,
'rating'= > 7/10,
Without you having to do anything, the following happens to your uploads resultset:
- Upload: id: 1 name: funny.mov type: video/quicktime bytes: 20480 created: 2008-06-01 14:47:23 fps: 30 bitrate: 376 rating: 0.7 UploadField: - id: 1 upload_id: 1 key: fps val: 30 - id: 2 upload_id: 1 key: bitrate val: 376 - id: 3 upload_id: 1 key: rating val: 0.7
As you can see the fps UploadField value has been updated and a new record with the key rating has been created. So this means you can use the CakePHP form helper to create different editors for your uploads like this:
$form->input('Upload.rating', array('options' => array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)));
And even so none of those fields really exist on the Upload model, everything will work just as if they would ; ).
How to use it
- Download the behavior from: the debuggable Scraps repository at github
- Place the expandable.php file into /app/models/behaviors/expandable.php
- Optional: Place the expandable.test.php file into /app/tests/cases/behaviors/expandable.test.php
- Create a table and model for UploadField with at least the fields shown above. (replace Upload with the name of your base model)
- Setup a Upload hasMany UploadField and UploadField belongsTo Upload association
- Add this to your Upload model:
var $actsAs = array('Expandable');
That is it. You are ready to go. Enjoy the magic ; ).
Please let me know what you think about this approach!
-- Felix Geisendörfer aka the_undefined
You can skip to the end and add a comment.
This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.