8

Because of other answers (like this), I'm just wanting to clarify what should be used in CakePHP 1.3.

Specifically, I have a situation that calls for a Model to depend on another, so from a method in that Model I'd like to load another, do some stuff with the info, etc.

The documentation for the App Class says:

In previous versions there were different functions for loading a needed class based on the type of class you wanted to load. These functions have been deprecated, all class and library loading should be done through App::import() now.

I'm assuming this covers the use of ClassRegistry, etc, but I just want to it to be clear, and certain:

Should I use App::import('Model', ...) to utilize one Model from another, or something else? If something else, what?

Community
  • 1
  • 1
anonymous coward
  • 12,594
  • 13
  • 55
  • 97
  • Since I can't comment on a revision in a behind-the-scenes way, I thought I would ask: I come to StackOverflow with the understanding that it's important for questions to be clear, and for others (likely via search engines) to be able to easily find questions in the future. Making my *version specific* question clear in the title seems to make perfect sense, in those cases. I don't agree with the edit, but I think I see what you're going for, and will let it stand. Is the tags-vs-title thing outlined in guidelines I missed somewhere? – anonymous coward Mar 08 '11 at 21:17

4 Answers4

13

It appears that, even two years since 2008, the best method is to use ClassRegistry::init(), despite the cited documentation.

This is made evident in the actual API/documentation for the specific classes/methods.

App::import()

Finds classes based on $name or specific file(s) to search. Calling App::import() will not construct any classes contained in the files. It will only find and require() the file.

ClassRegistry::init()

Loads a class, registers the object in the registry and returns instance of the object.

Examples Simple Use: Get a Post model instance ClassRegistry::init('Post');

As you can see, even the API Documentation points out examples of using ClassRegistry to load models, instantiating them for you, as opposed to App::import (which does much less), and despite the changed wording in the CakePHP "Book" documentation.

adriaroca
  • 172
  • 11
anonymous coward
  • 12,594
  • 13
  • 55
  • 97
  • `App::import()` exists for a reason. For example, you need a model instance in a behavior to work on all its default relationships (`belongsTo`, `hasMany`, `hasOne`, `hasAndBelongsToMany`). Now, if you also use `Containable` behavior and contain the data in `find()` call early, you get an incomplete set of relationships data by using `ClassRegistry::init()` (although there are workarounds that I explored and posted as a question and solution [here on SO](https://stackoverflow.com/q/52092268/1369473), but it's overly complex). It's always about what is right for the need, there's no generic way – Fr0zenFyr Sep 12 '18 at 04:58
7

If you can relate the models then the best way is to Dynamically bind the relations using

$this->bindModel("hasOne" => array("Model2")).

If you can't relate the model and you want to use the second model in just one occurrence then you can use

ClassRegistry::init('Model2')->find('allThatIWant');

if you want to use it in several occurrence then you must try

$this->model2 = & ClassRegistry::init('Model2') 
$this->model2->find('allThatIWant');
Curtis Gibby
  • 884
  • 1
  • 12
  • 25
RSK
  • 17,210
  • 13
  • 54
  • 74
  • 1
    plz remember `App::import()` is the worst method. Use if you only as a last attempt. – RSK Mar 09 '11 at 05:23
  • Okay, now I'm even more curious. Is this commonly discussed on the mailing list or something, because even the 1.3 documentation removed "other options" for accessing a model-within-a-model, and suggests App::import()... Is there anything that explains this clearly in the documentation? Thanks for your answer, and your help! – anonymous coward Mar 09 '11 at 16:41
  • 1
    check the comments of this post. http://nuts-and-bolts-of-cakephp.com/2008/12/16/how-to-build-a-dashboard-for-your-application-in-cakephp/ – RSK Mar 09 '11 at 17:32
2

As of 2.6.x of course it is ClassRegistry::init() still.

There is a major difference. App::import will just include/require it. On the other hand ClassRegistry::init() will instantiate it and fetch you a fully loaded object of the model.

So to say, for example you loaded a model in beforeFilter of your AppController. You add some custom properties to it using $this->Model->__something. Now you do call ClassRegistry::init('Model') somewhere where you do not have $controller object available, for example, in a behavior. The object returned by ClassRegistry::init('Model') will have your custom property $this->Model->__something in tact.

Btw, $controller->loadModel() seems the ideal way to load model where you have a $controller object available, for example in your components.

Arvind K.
  • 1,184
  • 2
  • 13
  • 27
  • `App::import()` exists for a reason. For example, you need a model instance in a behavior to work on all its default relationships (`belongsTo`, `hasMany`, `hasOne`, `hasAndBelongsToMany`). Now, if you also use `Containable` behavior and contain the data in `find()` call early, you get an incomplete set of relationships data by using `ClassRegistry::init()` (although there are workarounds that I explored and posted as a question and solution [here on SO](https://stackoverflow.com/q/52092268/1369473), but it's overly complex). It's always about what is right for the need, there's no generic way – Fr0zenFyr Sep 12 '18 at 04:57
-2

$this->loadModel('model name') will do unless u need it for the entire controller, Then just define the relationship in the model such as hasone, belongsto... and call $this->model->model2.

Justin Johnson
  • 30,978
  • 7
  • 65
  • 89