• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why call parent constructor when creating a model?

#1
[eluser]@robertotra[/eluser]
Hello,
I have a doubt about models in CI. User Guide says they are optional, in the sense that database manipulation can be inserted also directly into controllers:

Quote:CodeIgniter has a fairly loose approach to MVC since Models are not required. If you don't need the added separation, or find that maintaining models requires more complexity than you want, you can ignore them and build your application minimally using Controllers and Views.

So, using models is just about following MVC conventions and improve code readability, usability and maintenance, as User Guide says:

Quote:Instead of writing database operations right in the controller, queries should be placed in a model, so they can easily be reused later.

Anyway, if it is possible to manage databases inside controllers without calling any model, and using models is just about moving code about databases into them, why it is required to call the parent constructor when creating a model? They do not even connect automatically (or by parameter sent to the constructor) to a database, so what is parent constructor for? User guide says:

Quote:Make sure your class extends the base Model class.
The file name will be a lower case version of your class name. For example, if your class is this:
Code:
class User_model extends CI_Model {

    function __construct()
    {
        parent::__construct();
    }
}

Cannot models simply be loaded as any other custom library? Which are the methods of the parent class that we use and/or may skip into our implementation of a model?

Thanks for your reply
Best regards
Roberto



#2
[eluser]PhilTem[/eluser]
You ought to use the __construct method to have the magic __get method available throughout your model which works like this

Code:
public function __get($key)
{
    $CI =& get_instance();
    return $CI->$key;
}

That's actually the only thing why one uses the __construct-or (at least from my point of view). You can use the model as a pure library without extending the CI_Model, but then you'd have to write something like

Code:
class User_model {
    function __construct()
    {
        $this->CI =& get_instance();
    }
    
    function __get($key)
    {
        return $this->CI->$key;
    }
}

which ain't no deal-breaker at all Wink But don't forget to keep yourself DRY Wink

#3
[eluser]@robertotra[/eluser]
Maybe I've found the answer by myself... In a custom library we can use the super-object by getting its instance in a variable by reference and not by using the usual keyword $this, that is referred there to the new object of the custom library.

Instead, inside a model we can keep on using the keyword $this as referred to the main CI's object. That is we can use all functions of the ActiveRecord class as they are referenced in the user guide.

This mean also that if we do not call the parent constructors, we can still use the model, but in order to use the database connection and the ActiveRecord class' methods we should replace $this with $CI, as in any other custom library.

Is it correct? Any other reason?

Thanks
Roberto

#4
[eluser]@robertotra[/eluser]
Hi PhilTem,
we were writing at the same time... Smile
Thanks for enlightening !
Rob


[quote author="PhilTem" date="1327503068"]You ought to use the __construct method to have the magic __get method available throughout your model which works like this

[...]

That's actually the only thing why one uses the __construct-or (at least from my point of view). You can use the model as a pure library without extending the CI_Model, but then you'd have to write something like

[...]

which ain't no deal-breaker at all Wink But don't forget to keep yourself DRY Wink[/quote]

#5
[eluser]PhilTem[/eluser]
No problem. That's always the thing with non-live forums (rather than a chat where you see someone's typing Wink )

But glad to hear you solved it for yourself Wink

#6
[eluser]Aken[/eluser]
Including the constructor function in your models is optional. When you extend the CI_Model, it will automatically run CI_Model's constructor which will do the necessary connections to allow your model to use CodeIgniter's resources.

The benefit to using a constructor in your model is if you want to load resources or perform any other actions that are relevant to all functions in the model. This can include loading libraries (like the database), defining properties, sanitizing data, etc. When you do define a constructor in your model, you have to explicitly call the parent::__construct() function in it, otherwise it will overwrite CI_Model's constructor and you will lose CodeIgniter's resources.

This model is perfectly acceptable:
Code:
class Blog extends CI_Model {

public function get_all_posts()
{
  // Some code...
}

public function get_post_by_id($id)
{
  // Some code...
}

public function create_post($data)
{
  // Some code...
}

}

#7
[eluser]@robertotra[/eluser]
[quote author="Aken" date="1327572591"]Including the constructor function in your models is optional. When you extend the CI_Model, it will automatically run CI_Model's constructor which will do the necessary connections to allow your model to use CodeIgniter's resources....[/quote]

I know, but the problem arises when you want to make your own constructor in the model, as example to load the database resource (unless you want to load it into the various controllers each time before you load the model, which I found not convenient). AS explained in the User Guide:

Quote:Connecting to your Database

When a model is loaded it does NOT connect automatically to your database.

Since extending the class CI_Model does not connect automatically to the database (rightly, because different models can connect to different databases) I found convenient loading the database into the Model's constructor instead than inside the controllers loading it, that's why I was wondering about calling also the parent constructor.

#8
[eluser]Aken[/eluser]
Gotcha.

Looking at the code for CI_Model again, I was misleading. The constructor actually only calls the log_message() function for debugging purposes. The magic function __get() is what handles the automatic loading of CI resources.

So, you actually don't need to call the parent constructor at all if you have no need for the debug message. Which, in my opinion, is actually really vague anyway, since it just says "Model Class Initialized" - doesn't actually name the model at all.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.