Use one model within another

#1
[eluser]Peter Ivanov[/eluser]
Hello is it possible to
use the functions from one model within a function in another model

#2
[eluser]optimal[/eluser]
Hello,

It's possible, but you may want to describe what you're trying to accomplish to get a better response.

For example, are you trying to call a class-level (static) or instance method of your model? If it's a static function you can just call BModel:Confusedome_method() from an AModel function.

If you're working with instance methods you'll need to decide how the two instances know about each other. Will you pass a reference of the first instance to a method in the second?

Also, what's the relationship between the two models. Is one a descendant of the other, or does one own the other (composed of the other).

Could this all be better managed by a controller instead? Ideally a controller would act as the go-between for the two models.

#3
[eluser]Peter Ivanov[/eluser]
yes it posible i just have test it now



/* Model A file */
class ModelA extends Model {

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

function test(){
exit('You have called function from model A in model B');
}
}



/* Model B file */
class ModelB extends Model {

function __construct(){
parent::Model();
$this->load->model('ModelA_model','model_a',true);
$this->model_a->test();
}
}




it prints 'You have called function from model A in model B'

#4
[eluser]marcoss[/eluser]
And the short answer is yes, they are classes after all, so you can use as many instances as you want Wink

#5
[eluser]thurting[/eluser]
I just tried this out and found it interesting that if you load a model using $this from within another model, you will only be able to access the secondary model if it was loaded from within the primary model's constructor. If that is hard to read, check the following code:

The below will work:
Code:
class Test extends Model
{
  function Test()
  {
    parent::Model();
    $this->load->model('new_model');
  }

  function hello()
  {
    print_r($this->new_model);
  }
}

The below will NOT work and you will get something like Undefined property: Test::$new_model:
Code:
class Test extends Model
{
  function Test()
  {
    parent::Model();
  }

  function hello()
  {
    $this->load->model('new_model');
    print_r($this->new_model);
  }
}

If you run print_r($this) in the hello() method on the second example you will see that the $CI->[load]->[_ci_models] shows 'new_model' but it doesn't seem to have loaded it properly. Anyone know why all of the above holds true?

#6
[eluser]Mirage[/eluser]
@teamhurting:

This is because CI only assigns previously loaded libraries to new instantiated ones. So the last library loaded never has $this access to anything loaded after it. While the Loader could use some general tweaking to make this more transparent, the following is the legitimate CI workaround:

Code:
class SomeModel extends Model {

    function someFunction() {
        $CI =& get_instance();
        $CI->load-model('OtherModel','',true);
        $foo=$CI->OtherModel->otherFunction();
}

/* Alternatively use a class variable if you must access
     other models in a lot of functions */

class SomeModel extends Model {

    var $CI;
    var OtherModel;

    function SomeModel {
        parent::Model();
        $this->CI =& get_instance();
        if (is_null($this->OtherModel) {
            $this->OtherModel=$this->CI->load->model('OtherModel','',true);
        }
    }


    function someFunction() {
        $foo=$this->OtherModel->otherFunction();
    }

}

#7
[eluser]thurting[/eluser]
Thanks for the response. I should have gone straight to the source and checked out that _assign_libraries() function in the Model definition. I was wondering how a Model could access CI instance variables/methods using $this. The idea of Model extending CI didn't make sense to me. Your solution of directly working with CI instance is easiest. However, if I have the time, I may write a little function that updates all relevant object instances when a library is loaded. Some sort of listener/broadcaster functionality attached to the loader class. We'll see if I have the time (and true desire Smile).

#8
[eluser]ImageSmith[/eluser]
Thanks Mirage, that's gold.
I've been pondering this problem for a while and thought that maybe I was doing something wrong in my code.
This sort of info should be in an faq section in the code docs.


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


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