views:

3786

answers:

4

I am writing a webapp using CodeIgniter that requires authentication. I created a model which handles all my authentication. However, I can't find a way to access this authentication model from inside another model.

Is there a way to access a model from inside another model?

or

Is there a better way to handle authentication inside CodeIgniter?

+3  A: 

In general, you don't want to create objects inside an object. That's a bad habit, instead, write a clear API and inject a model into your model.

<?php
// in your controller
$model1 = new Model1();
$model2 = new Model2();
$model2->setWhatever($model1);
?>
Till
Is this a good practice? Because the user of Model2 has to know, that it is dependent on Model1.What is the good practice?
Sabya
Yes, better practice to "inject" the dependency, vs. initializing the Model2 inside Model1.
Till
That doesn't sound good from a DRY standpoint. What if I have a function that changes an aspect of one model and triggers an action for another model?
wag2639
I totally agree - model2 shouldn't go into model1 to start with. But if it's necessary, this is the best you can do.
Till
+1  A: 

Don't handle authentication in your model. Only use models to interface with your database, or ldap or whatever.

I created an Auth library that I use to manage authentication and authorization. You can access a library like this from your controllers.

+2  A: 

It seems you can load models inside models, although you probably should solve this another way. See CodeIgniter forums for a discussion.

class SomeModel extends Model
{
  function doSomething($foo)
  {
    $CI =& get_instance();
    $CI->load->model('SomeOtherModel','NiceName',true);

    // use $CI instead of $this to query the other models
    $CI->NiceName->doSomethingElse();
  }
}

Also, I don't understand what Till is saying about that you shouldn't create objects inside objects. Of course you should! Sending objects as arguments looks much less clear to me.

Christian Davén
The complaint is that doing it that way unnecessarily creates a stronger dependency betweeen the two models. When you're testing, for example, it's nice to be able to give SomeModel a mock version of SomeOtherModel; you can't do that if the former is directly loading the latter. Or you modify the code later to use a different model with the same interface, such as when you're refactoring existing code to use a plugin system.
Rob Howard
Google has an open source dependency injection framework. It's for Java but it explains the pros and some of the cons of dependency injection.http://code.google.com/p/google-guice/
Juan Mendes
A: 

I disagree about handling authorization in the controller. I handle all my authorization in my model; typically I handle it in the database. If they aren't authorized, it looks just like it doesn't exist in the database.

As for dependency injection, it does make testing much easier. I wouldn't say never create an object in another object, after all some languages only have objects. Like everything, its a trade-off, so I think its more important that you consider your situation and what will serve you best in that instance.

If they're objects who classes you are responsible for and thus you need to test independently, then dependency injection can help. It also can help if you think you might change implementations; perhaps if you are running an e-commerce site and you switch from PayPal to Authorize.net