Welcome Guest, Not a member yet? Register   Sign In
Model and Form
#1

(This post was last modified: 11-20-2014, 04:14 AM by aurelien.)

Hello,

I'm new user of MVC and I have a few questions regarding Models.

If you read this tutorial you can see

Model
PHP Code:
public function set_news()
{
 
   $this->load->helper('url');

 
   $slug url_title($this->input->post('title'), 'dash'TRUE);

 
   $data = array(
 
       'title' => $this->input->post('title'),
 
       'slug' => $slug,
 
       'text' => $this->input->post('text')
 
   );

 
   return $this->db->insert('news'$data);


Why is it better to read inputs from Forms into Models rather than into Controllers ?
Is it not "more MVC" to read inputs from Forms into Controllers ?

Like this
Controller
PHP Code:
public function create()
{
 
   ...
 
   $this->load->helper('url');

 
   $slug url_title($this->input->post('title'), 'dash'TRUE);

 
   $data = array(
 
       'title' => $this->input->post('title'),
 
       'slug' => $slug,
 
       'text' => $this->input->post('text')
 
   );

 
  $this->news_model->set_news($data);


Model
PHP Code:
public function set_news($data)
{
 
   return $this->db->insert('news'$data);



Thanks for your help !  Smile
Reply
#2

Its because you have then clean data in the mvc philosophy as discussed also here:

http://forum.codeigniter.com/thread-29.html

In the model in a web context normaly you get the data and nothing else. Thats why you forced to do all the needed business logic in the controller (like get the input data).

But it depends on you if you want programm in your project in a clear mvc way or in your own way. but you should go with mvc ;o)

Reply
#3

In the first example you are making a trivial storage operation dependent on other class (CI_Input) and thus the method looses flexibility. In order to reuse this method in different contexts remove this dependency - the second example is better.
Reply
#4

(This post was last modified: 11-20-2014, 07:59 AM by bclinton.)

(11-20-2014, 05:00 AM)ivantcholakov Wrote: In the first example you are making a trivial storage operation dependent on other class (CI_Input) and thus the method looses flexibility. In order to reuse this method in different contexts remove this dependency - the second example is better.

I agree.  Your second example is better.  That tutorial should probably be updated.
Reply
#5

(This post was last modified: 11-20-2014, 04:16 PM by slax0r.)

I tend to keep all of data operations in the models. Read the input with the controller, and pass it into the model. Then let model do with the data what it needs to do. This also includes preparing an array for database insert.
I like to keep controllers thin, and models fat.
I tried a different approach before, where I would prepare data to some degree in the controller, as you do in your second example.
After a while, the controllers grew out of hand. They became this unreadable piece of code.
But if I did most of this stuff in the models, I could group methods easier and keep it across more models logically.

Thank god that project got dumped, and fingers crossed it doesn't get picked up again.
Reply
#6

(11-20-2014, 04:11 PM)slax0r Wrote: I tend to keep all of data operations in the models. Read the input with the controller, and pass it into the model. Then let model do with the data what it needs to do. This also includes preparing an array for database insert.
Kind of new to MVC here, so trying to understand. If you read the input with the controller and then pass it to the model, don't you have to put it in an array? And if you validate the input in the controller, and then put it in an array, isn't the data already prepared for database insert?

I understand the concept of pushing logic down the hierarchical chain. That was a rule even under structured programming. But code reuse was not big under structured programming. If you make a method in a model do "too much," doesn't it become single purpose. How do you balance that?
Reply
#7

(11-20-2014, 05:59 PM)RobertSF Wrote:
(11-20-2014, 04:11 PM)slax0r Wrote: I tend to keep all of data operations in the models. Read the input with the controller, and pass it into the model. Then let model do with the data what it needs to do. This also includes preparing an array for database insert.
Kind of new to MVC here, so trying to understand. If you read the input with the controller and then pass it to the model, don't you have to put it in an array? And if you validate the input in the controller, and then put it in an array, isn't the data already prepared for database insert?

I thnk by data operations he meant database operations.
Reply
#8

Well no, not limited only to database. Models can be used for other data storage beside database.

After validation, data should be as it is for insertion to a database yes. But there are other cases where you need to prepare the data even further. Example, user password change. If you are using PHP function password_hash for hashing passwords, you first have to retrieve the password from the database, to check the old password with password_verify. And then if the old password is correct, and the new passwords are confirmed to be the same(through validation), you need to update the user record. I would do that sort of thing in the model. Because I could then just copy the model to a new project, and already have all the functionality for password changing, all I would need to do, is a new view and controller method that calls the model method for password changing.
I also tend to do all the data validation in a model, yes, it makes the model depend on the form validation library, but it has a dependency for CI database library before that, so I don't see a bad thing here, because moving a model to a different framework will include much of overwrite anyway. The validation rules can be however set from a controller, if there is a need to, but I have a default set of rules defined in the model. Or skip the whole validation, if the situation requires it.
To minimize the code even further, and not have to rewrite this over and over again from model to model or app to app, I use a base model in a combination with a base controller. A simple form insert/update requires me to write almost no code, all I need to define, is a controller, not even a method, because a default one is defined in the base controller, and validation rules in the model, or in the controller method should I wish to define it.

I also tend to retrieve the whole POST/GET array at once in the controller, with
Code:
$this->input->post(); // or ->get();
To remove multiple function call overhead, and then proceed doing everything in the array.
Reply
#9

In most cases, I keep my validation rules in the model and have a method in the base model (get_validation_rules()) to return the validation rules. Then my controller can do the following:




PHP Code:
$this->form_validation->set_rules($this->some_model->get_validation_rules());

// Add more rules if necessary

// Validate
if ($this->form_validation->run() === false) { 
 
   return false;
}

// Since the data is valid, 
// give it to the model
$data $this->some_model->prep_data($this->input->post());

if (
$insert) {
 
   $result $this->some_model->insert($data);
} else {
 
   $result $this->some_model->update($data);
}

// do whatever else needs 
// to be done before returning 

Since the method to get the validation rules (and prep, insert, and update the data) is in the base model, I have the flexibility to choose when and where I use them without writing a bunch of boiler-plate code for each model. Some models might need a heavier controller to handle odd circumstances, while others might not need much more code than what I've included above (or could even trim that down by handling the decision to insert/update in the model).

I have a handful of odd models to do things like read data from an array (maybe pulled from a file, or even stored in a property in the model) which still use the same methods used in the base model for data access. This allows me to move the data to the database later, if needed, without changing my controller(s) and/or view(s). In many cases, I can do it by just changing the base class of my model or removing the custom (overriding) methods from the model.
Reply
#10

(12-12-2014, 03:21 PM)mwhitney Wrote: In most cases, I keep my validation rules in the model and have a method in the base model (get_validation_rules()) to return the validation rules. Then my controller can do the following:

Perhaps it's a matter of personal preference, but I don't agree with that method.  Form Validation is a natural function of the controller in my opinion.  It should be the first thing your controller does in most cases.  The controller is opening the door to your server when it accepts requests and form input.   The lock should be on the front door, not in the kitchen.

Forms pass data to a controller.   When that form data does not validate, the controller sends the data back to the user with error messages.  Why should the model enter into this clear request/response exchange when it is completely unnecessary?  Why should you even load a model if you know it's not going to be needed in the case of failed validation?
Reply




Theme © iAndrew 2016 - Forum software by © MyBB