First, I call private functions to parse the specific checkbox ids ( Ex. parseCategories()), but they all just call parseResource().
Next, while in parseResource() I look into the variables scope for the model (Ex. _Size) to dynamically get the object by using findByID().
Lastly, I append the object to an array and populate the Product object and save it.
ProductController.cfc
/**
* @accessors true
* @action list
* @extends coldmvc.Controller
*/
component {
property _Size;
property _Color;
property _Category;
function save() {
var product = _Product.new();
params.product.categories = parseCategories(params.product.categories);
params.product.sizes = parseSizes(params.product.sizes);
params.product.colors = parseColors(params.product.colors);
product.populate(params.product);
product.save();
redirect({controller="product",action="setup"},"productID=#product.id()#");
}
private array function parseCategories(string categoryIDs) {
return parseResource("Category",arguments.categoryIDs);
}
private array function parseSizes(string sizeIDs) {
return parseResource("Size",arguments.sizeIDs);
}
private array function parseColors(string colorIDs) {
return parseResource("Color",arguments.colorIDs);
}
private array function parseResource(string resource, string resourceIDs){
var resources = $.string.toArray(arguments.resourceIDs);
var result = [];
var i = "";
for (i=1; i <= arrayLen(resources); i++) {
arrayAppend(result, variables["_#arguments.resource#"].findByID(resources[i]));
}
return result;
}
}
I wanted to share this just in case someone else is running into the issue.
Instead of using Model.findByID(), which requires ColdMVC to parse your method name to figure out what you want to do, you could use Model.get(), which does a lookup using the PK.
ReplyDeleteGood use of checking the variables scope for the injected Model. I was actually thinking of adding a ModelFactory to ColdMVC that might help simplify scenarios like this, but it looks like you found a decent workaround. In case you're curious, the ModelFactory would look like such:
arrayAppend(result, modelFactory.get(resource).get(resources[i]));
Maybe instead of modelFactory.get(model) it should be modelFactory.getModel(model). Thoughts? Should I add it?
Update: I forgot ColdMVC also supports Modal.getAll(), so instead of looping over the list of checkboxes, your parseResource function could be a lot smaller:
ReplyDeletefunction parseResource(string resource, string resourceIDs) {
return variables["_#resource#"].getAll(resourceIDs);
}
@Tony
ReplyDeleteYeah I like modelFactory.get(resource).get(resources[i]). That would come in handy. It took me awhile to figure out where the _Model was being stored at.
FYI,
ReplyDeleteI added the modelFactory like we had talked about. I also updated the populate method to automatically populate relationships using IDs. So in your case, you could update your save method to simply be:
function save() {
var product = _Product.new(params.product);
product.save();
redirect({controller="product", action="setup", id=product});
}
Can't get much simpler than that. :)
Sweet, that works for me.
ReplyDelete