model vs controller
#1
Posted 07 February 2012 - 03:30 PM
I am somewhat in doubt where to put the methods.
#2
Posted 07 February 2012 - 04:00 PM
#3
Posted 07 February 2012 - 04:30 PM
#4
Posted 07 February 2012 - 05:28 PM
Make models as fat as you can and in controllers use model functions, render, access session etc.
#5
Posted 07 February 2012 - 05:44 PM
It also eliminates the strange need to call another controller from a controller..
If you develop that need, you know you need to re-factor your code: controller code needs to be moved into a model.
You can instantiate a model from practically anything.
#6
Posted 07 February 2012 - 06:15 PM
Put any code that references HTTP interactions in controllers. So code that reads variables from form inputs, uses sessions, uses cookies, and code that calls for renders or redirects goes in the controller.
#7
Posted 07 February 2012 - 06:46 PM
This also means that you can automate your app through cron scripts, commands, etc. later if need be.
#8
Posted 08 February 2012 - 01:58 AM
$file = CUploadedFile::getInstance($this, 'file'); // other manipulations...
But it is an indirect access to $_FILES array, and like accessing $_GET or $_POST values inside a model it should be a bad practice? CFileValidator does the same. Any thoughts?
#9
Posted 08 February 2012 - 02:39 AM
Accessing $_FILES in model makes testing much harder. It's better to pull data from global arrays in controller, and then copy relevant informations into model. Not as efficient but easier to maintain.
"Never memorize what you can look up in books."
Albert Einstein
#10
Posted 08 February 2012 - 11:15 AM
A perfect example of what a controller should handle.
#11
Posted 08 February 2012 - 11:46 AM
andy_s, on 08 February 2012 - 01:58 AM, said:
$file = CUploadedFile::getInstance($this, 'file'); // other manipulations...
But it is an indirect access to $_FILES array, and like accessing $_GET or $_POST values inside a model it should be a bad practice? CFileValidator does the same. Any thoughts?
I prefer to get uploaded file instance in the controller and then pass it to the model, something like this:
//controller
$uploaded = CUploadedFile::getInstance($model, 'attachment');
if ($model->validate() && $model->createAttachment($uploaded)) {
$model->save();
}
This way file processing code is still in the model, but access to $_FILES becomes more indirect.
For tests, for example, I can extend CUploadedFile and emulate uploaded file.
And then this mock object can be passed to the $model->createAttachment(...).
#12
Posted 08 February 2012 - 12:03 PM
#13
Posted 08 February 2012 - 01:43 PM
andy_s, on 08 February 2012 - 12:03 PM, said:
I understand your point, but I still think that manipulation with CUploadedFile makes sense, because it is the model should decide where the file should be saved. For example, User model can save logo file to the files/logos/{user_id} folder and Post model can save file to the files/posts/attachments and so on.
#14
Posted 08 February 2012 - 01:47 PM
seb, on 08 February 2012 - 01:43 PM, said:
No doubts, only the model should know where its files are stored and how to save/get them. I just don't like the fact I should rely on CUplodedFile class inside models, because it's always associated with $_FILES array
#15
Posted 08 February 2012 - 02:15 PM
The model should be able to deal with any file, not only uploaded files.
#16
Posted 08 February 2012 - 03:59 PM
andy_s, on 08 February 2012 - 01:47 PM, said:
Yes, but as I mentioned above the reference to $_FILES becomes indirect, so we can extend CUploadedFile class and have, for example, TestUploadedFile which takes it's source file not from php temp folder, but from a folder with test files.
I can not say that I feel that CUploadedFile in the model is absolutely correct, but I see no valuable disadvantages and think it is OK.
jacmoe, on 08 February 2012 - 02:15 PM, said:
The model should be able to deal with any file, not only uploaded files.
I think that it is better to keep code which saves uploaded file in the model, because controller should now know where and how to save uploaded file. Actually I usually use a bit more complex approach then I described above.
I have a db table 'files' with files metadata (user name, system path, size, etc) and a model File. All direct file operations (file system level functions like create, copy, move file) are performed only through the File model.
So file upload process is:
- controller creates CUploadedFile instance and passes in to the model (for example, Post)
- Post model has 'file' relation (File model) knows where to save file, creates new File instance, configures it and calls $file->upload($uploadedFile)
- File model performs real file operation (moves temp file to apermanent storage).
This way code in controllers and models to handle files becomes 'slim' and the main file handling logic is in the 'fat' File model. Also with such approach it is easy to replace file storage (for example, switch from a local file system to Amazon S3) - I need to modify only File model to do this.
#17
Posted 08 February 2012 - 04:51 PM
A CUploadedFile doesn't make much sense outside of a submitted form, though. Which ties it completely to the controller.
It just feels wrong to me to let the model handle it.
So for brevity, I would just put the logic in a component instead. Like a component wrapping a component.
#18
Posted 08 February 2012 - 05:10 PM

Help















