Welcome Guest, Not a member yet? Register   Sign In
Using models from within models
#1

[eluser]XedinUnknown[/eluser]
Hi all!

I hate to revive dead threads, but I felt that creating another one would be too much, since this one's problem is apparently still in question, and it only has two pages, so....

I have come across the same problem as the author. And, from what I've read here, CI's creators think it is useless to call another model's methods from within a model, and thus have designed it in a way to make it difficult to do so. However, it says in the manual that the architectural goals of CodeIgniter are "flexibility", "loose coupling" and "singularity". Well, how can you achieve those, if the components of the system cannot use one another..? What flexibility and reuseability are we talking about then..? I think it is perfectly rational to invoke objects from other objects. I think that "loose coupling" does not mean "insane incapsulation". One object is not supposed to perform all work in my opinion. And I totally agree that it is definately not OOP to do as CI intends. Moreover, there is nothing deviating from the MVC approach. Magento, one of the best (but, unfortunately, one of the most poorly documented) packages, does this all the time; it is essential to do this in Magento. This is not an attempt to advertise the eCommerce solution...

So I'd really like to know how to invoke a model's method from within another model. I have done as it says in the Manual (used the get_instance method), and it kinda works, but not as expected. You see, the problem is that CI stores the invoked models somehow inside, but from within one model it is impossible to know whether another model, or another model with the same name, has been instanciated before, and this leads to a disaster when addressing these models. Especially this goes crazy when specifying a second parameter while loading, like so:
Code:
$this->load->model('Model_name', 'fubar');
This is very frustrating. Please, if someone knows how to do this properly, tell me, as I really need this kind of functionality.

Thanks.
#2

[eluser]XedinUnknown[/eluser]
So... wiredesignz has pointed me to this helpful topic. I haven't yet tried it, but I will. I'll also post the results in this topic.
Thanks, wiredesignz! :-)
#3

[eluser]jedd[/eluser]
[quote author="XedinUnknown" date="1260995269"]
{ complaints about CI being different to other frameworks removed }
. . .
So I'd really like to know how to invoke a model's method from within another model.
. . .
This is very frustrating. Please, if someone knows how to do this properly, tell me, as I really need this kind of functionality.
[/quote]

Perhaps you could describe what you are trying to do from a more generic point of view. Calling models from within other models is do-able, but indicates poor design. Consequently you either keep forcing your way down a bad design path, or you reverse up a bit and try a different (and probably more elegant) approach.
#4

[eluser]XedinUnknown[/eluser]
jedd,

First of all, I am not complaining that CodeIgniter is different from other frameworks. I am complaining that it's lacking essential features.
If the framework does not allow usage of classes from other classes, this means that to utilize their functionality you must either rewrite code, making it not reusable, or pass lots of data from one to another from outside (in this example, through controllers), making it very inconvenient and bringing it further from the idea of OOP.

Please explain how is the need to use class's functionality from elsewhere a sign of poor system design..?

Also, if there's an elegant approach to facilitate similar functionality, please point me to the solution.

You are asking me to describe my problem. However, in this case it is irrelevant what exactly the problem is. I just need to use functions of one model from another. In my opinion, this is the what, and not the how.

I have always been wondering, why in CI the Models are separated from Libraries. They all can provide the same functionality, including interaction with a database, so I don't see you they actually different. I am writing about this because one way to achieve what I want would be to create libraries instead of models, but this is not logical at all.
Perhaps, you could explain it to me?

Thanks for your attention.
#5

[eluser]BrianDHall[/eluser]
Heck, I thought you always had to use get_instance in a model to access the ci super-object and therefore other models. I just figured models should be assigned to the super-object, not inside each other.

Maybe I'm late to the party, but I haven't had an issue with models calling other models. I thought something like this in a model worked fine:

controller:
$this->load->model('Mainmodel');

mainmodel:
$ci =& get_instance();
$ci->load->model('Model2');

$result = $ci->Model2->model_function();


You can then do a simple isset($ci->Model2) check to see if a model is already loaded into CI.
#6

[eluser]jedd[/eluser]
[quote author="XedinUnknown" date="1260997648"]
First of all, I am not complaining that CodeIgniter is different from other frameworks. I am complaining that it's lacking essential features.
[/quote]

Okay then .. bemoaned. Smile

Responses to this are:
o it's an essential feature that is actually present (as others have pointed out to you),
o if all frameworks had all the same features, then you'd only need one framework,
o different frameworks offer different features and approaches, so you have to pick the one that matches (or most closely matches) your requirements - everything is a trade-off.

Quote:If the framework does not allow usage of classes from other classes, this means that to utilize their functionality you must either rewrite code, making it not reusable, or pass lots of data from one to another from outside (in this example, through controllers), making it very inconvenient and bringing it further from the idea of OOP.

The fact that you are under the mis-belief that these are the only two options available to solve your underlying problem .. is kind of why I keep asking you to describe your underlying problem in more detail. Telling me that your design is irrelevant, when it so very clearly is (look at the number of people asking the same question you are, compared to the number of people using CI - that's a big hint) is not hugely helpful here.

You later ack the presence and potential use for libraries - but for some reason didn't include that in the two options above.

Claiming that all you're doing is innocently wanting to call one class from another - whilst technically accurate - disguises or ignores the features and methodology of CI's MVC paradigm. What you want is for two models to be talking to each other. Let's be very clear about this, and use accurate terms.
#7

[eluser]XedinUnknown[/eluser]
Quote:What you want is for two models to be talking to each other. Let’s be very clear about this, and use accurate terms.
Correct, I do want two models to be talking to each other. Is this a sign of poor design..?
#8

[eluser]jedd[/eluser]
[quote author="XedinUnknown" date="1260998709"]
Correct, I do want two models to be talking to each other. Is this a sign of poor design..?[/quote]

I think so, yes.

I'll ask, naively, why you want two models to talk to each other. You might respond with 'it doesn't matter', but I'll ask anyway.

I know this is the third time I've asked, but I'm an optimistic chappy. I don't want detail, I don't want your IP, I don't want to steal your code or your ideas. I just want enough to then offer suggestions on other ways of approaching the problem.

At the moment I don't know anything about your design.

For example, whether you have a one-model-per-table design, or if you've got multiple database tables managed by each model.

Whilst you might think that this kind of information is somehow not important, I'm not sure how many times I can tell you that it is before I start to lose interest.

Oh, and please don't reply with a single-sentence response answering just that one question - I'll clarify again that an over-view of your design, and what you're trying to do, and why you're trying to use one model from another, and whether this is a one-off or something you're trying to do amongst all your models ...

Feel free to share all this information up front, rather than continue with the blood-from-a-stone approach of being helped.
#9

[eluser]intractve[/eluser]
[quote author="BrianDHall" date="1260997843"]Heck, I thought you always had to use get_instance in a model to access the ci super-object and therefore other models. I just figured models should be assigned to the super-object, not inside each other.

Maybe I'm late to the party, but I haven't had an issue with models calling other models. I thought something like this in a model worked fine:

controller:
$this->load->model('Mainmodel');

mainmodel:
$ci =& get_instance();
$ci->load->model('Model2');

$result = $ci->Model2->model_function();


You can then do a simple isset($ci->Model2) check to see if a model is already loaded into CI.[/quote]

Hi,
I do not believe you need to get_instance inside a model.
Models Views & Controllers have access to the $this variable (the current instance) directly.

I have one project that has a 'site' model loaded automatically and another 'reports' that's loaded when reports are called for.

In one of the model functions under reports I needed to call a function in 'site'.

So under the getreports() function (in my model)
I did $this->site->getusersname($uid);
and it works,

Maybe this is the same thing the chap who opened this thread wants.
You do not have to autoload the model either,
you can call $this->load->model('whatever') in any function in a Model, View or Controller

That's why CodeIgniter is considered 'loose' in its implementation of the MVC architecture
#10

[eluser]XedinUnknown[/eluser]
jedd,

As an example, I have a model "Customer", a model "Order", and a model "Product".
I want to list all products of an order, like so:
Code:
Order->getAllProducts();
Or I would like to create and get an order of a customer, for example:
Code:
$new_order = Customer->createOrder();
I may also want to do something like the following from within an Order model:
Code:
$customer = Environment::getSingleton('customer/checkout')->getCurrentCustomer();
The use of singletons makes the system very flexible, and efficient at the same time, not to mention that it is very convenient. Could you offer an alternative to this..?

intractve,

What you have shown me is exactly what I am trying to do, and I can confirm that it kinda works. However, imagine a situation like this:
Code:
// Inside a controller
$this->load->model('customer', 'user');

// Inside the 'Customer' model
$this->load->model('user', 'user');

This code didn't work for me. As far as I could tell, the second one was either not beind loaded at all, or was overriding the first one, I am not sure. I could not know from inside the Customer model, what other models where loaded before. I think the cause of the problem is the absence of Namespaces and Singletons. Correct me if I'm wrong.




Theme © iAndrew 2016 - Forum software by © MyBB