[Coldbox 4] modelsLocation and modelsExternalLocation

I have a couple dozen plugins that I am working on converting over from 3.5.3 and I am having trouble getting models recognized and injected with wirebox.

when I dump wirebox.getBinder().getMappings() it seems to have gotten all my services from the model/service folder but it does not seem to know about the .cfc’s in the base model folder.

I know that the model folder has been renamed to models in CB4 but I have added modelsLocation = “model”, to my config however it does not seem to have any effect. I also added modelsExternalLocation = “global.model”, and they do not seem to be getting loaded either.

I cant seem to find any information about modelsExternalLocation in the docs but I found confirmation that it should be a viable solution here Google Groups

I have also tried adding it my wirebox scanlocations like this

scanLocations = ["/globals/model"],

but it still does not seem to pick it up.

One thing you should realize about the model location is it simply sets the default scan location. This is an implicit lookup meaning the mappings are created on-the-fly the FIRST time a model is requested. Therefore, WireBox will not have mappings for any models you’ve never asked it to create if that model is just sitting in a scan location. This is different from when you use the map().to() or mapDirectory() DSL which explicitly adds mappings when WireBox starts up.

Can you show the exact file path your CFC lives in and the exact code you’re using to retrieve it? Also, does it work if you put the CFC in a folder called “models”?

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Adding the scan location manually is no different than editing the ColdBox model convention location. Inside ColdBox, when it loads up WireBox, it simply sets the model location and all external model locations as scan locations in WireBox. It’s basically just a convenience.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

In the ORM entity I am calling

property name=“SettingWrapper” persistent=“false” inject=“model:SettingWrapper”;

my settingWrapper.cfc lives in G:\apps\lib\model\utility\ and I have added the following to my coldbox.cfc

//Mappings
modelsLocation = “/model”,
modelsExternalLocation = “global.model”,

and to the wirebox.cfc
// Package scan locations
scanLocations = ["/global/model",“global.model”,“global.model.utility”,“model”,"/model"],

I was not sure if it recursively scanned so I went ahead and added the child directory, I have also moved the CFC to a new models directory in the webroot of the app and it does not seem to make a difference.

Scan locations do not include subfolders in the same way that handlers, views, and layouts locations don’t. You must specify the full path starting at the root of the scan location. If you want WireBox to map every CFC in a folder and its sub fodlers, use the mapDirectory() DSL.

I would suggest backing up a bit-- it seems like you’re just adding every configuration you can think of. Let’s omit the ORM entity and just do a simple wirebox.getInstance( ‘SettingWrapper’ ) to see if WireBox can find the SettingWrapper CFC. If so, we’ll move on to injecting it. Chances are, your ORM entity is being created in such a way that it’s not getting autowired.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

Ok, it looks like with

scanLocations = [“global.model.utility”],

it can find the settingswrapper.cfc in the utilities folder but it does not seem to care about the locations defined in modelsLocation or modelsExternalLocation. Assuming that wirebox knows about the cfc, what could cause the injection to fail?

Before we deal with injection, I want to address again what I think is a misunderstanding on your part for scan locations. When I said, “You must specify the full path starting at the root of the scan location” here is what I mean.

Let’s say you have a model here:

/model/utility/settingswrapper.cfc

You set the scan location (or model location convention) to “model”

And then, you access it like so:

getInstance( “utility.settingswrapper” )

Note, the “utility” is part of the model path. This is how scan locations work. You point to a root folder and specify the FULL path up to the CFC from inside that folder.

Now, sure you can create a separate scan location for every subfolder inside, but that’s sort of defeating the point. If you like to ask for a model by the model name only (which is my favorite), then we can do that but scan locations are designed for that.

In our /config/WireBox.cfc file we can create an explicit mapping like so:

map( “settingswrapper” ).to( “model.utility.settingswrapper” )
Or that line can just be shortened to the following if you intend for the mapping name to match the name of the CFC
mapPath( “model.utility.settingswrapper” )

And finally, if all the CFCs in your model folder and its sub directories have unique names, you can recursively map the entire folder and its sub directories in a single command:

mapDirectory( “model” )

If this makes sense, we’ll move on to our ORM injection.

Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: brad@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com

That part makes perfect sense, thank you. I guess what I don’t understand is how the convenience config items (modelsLocation, and modelsExternalLocation) work? If I understand correctly they should basically just be getting added to scan locations in the end, but that does not seem to be working? If i try to access a model in my model directory I get the following error dispite having the modelsLocation = “model” config in my coldbox.cfc

The instance could not be located in any declared scan location(s) (models,global.model) or full path location