Refactoring Save Method

All,
I am always struggling with the best way to refactor so I would like your thoughts on this. Let us say your trying to save a category that looks like this.

component persistent=“true” extends=“catalogadmin.model.BaseEntity” {

property name=“categoryid” type=“numeric” ormtype=“int” fieldtype=“id” generator=“increment”;
property name=“name” type=“string” ormtype=“string”;
property name=“description” type=“string” ormtype=“string”;
property name=“metakeywords” type=“string” ormtype=“string”;
property name=“metadescription” type=“string” ormtype=“string”;
property name=“metaPageTitle” type=“string” persistent=“false”;
property name=“isactive” type=“boolean” ormtype=“int”;
property name=“sort” type=“numeric” ormtype=“integer”;
property name=“alias” type=“string” ormtype=“string”;

property name=“categories” fieldtype=“one-to-many” cfc=“Category” fkcolumn=“parent”;
property name=“parent” fieldtype=“many-to-one” cfc=“Category” fkcolumn=“parent”;
property name=“template” fieldtype=“many-to-one” cfc=“catalogadmin.model.template.CategoryTemplate” fkcolumn=“templateid”;

public Category function init(){
setIsActive(true);
return this;
}

}

Your first attempt might look something like this (parent & template are many-to-one relationships)

public void function save(){
var rc = event.getCollection();

var template = categoryTemplateService.get(1);
var parent = categoryService.get(rc.parent);

rc.category = categoryService.get( rc.id );
rc.category.setName(rc.name);
rc.category.setAlias(rc.alias);
rc.category.setDescription(rc.description);
rc.category.setMetaKeywords(rc.metakeywords);
rc.category.setMetaDescription(rc.metadescription);
rc.category.setIsActive( event.getValue(“isactive”,false) );
rc.category.setParent(parent);
rc.category.setTemplate(template);

categoryService.save(rc.category);

getPlugin(“messagebox”).setMessage(“info”,“Category saved!”);
setNextEvent(‘category/list’);
}

That is a little messy and doesn’t take into account 2 big steps, data validation and error handling. In the next go around I am just going to mock validation to keep this simple

public void function save(){
var rc = event.getCollection();

// populate the model with all the properties
rc.category = populateModel( model=categoryService.get(rc.id),exclude=“parent,template,isactive” );
// many-to-one
rc.category.setParent(categoryService.get(rc.parent));
// many-to-one
rc.category.setTemplate(categoryTemplateService.get(rc.template));
// checkbox does not exist
rc.category.setIsActive(event.getValue(“isactive”,false));

// validation mock will be replaced with actual validation later
if( isValidModel(rc.category) ){

try {
categoryService.save(rc.category);
getPlugin(“messagebox”).setMessage(“info”,“Category saved!”);
setNextEvent(‘category/list’);
} catch(any e) {
// write to log

// tell user
getPlugin(“messagebox”).setMessage(“error”,“There was a problem trying to save the category, please try again.”);
setNextEvent(event=‘category/edit’,persist=“category”);
}

} else {
getPlugin(“messagebox”).setMessage(“error”,“Your form had validation errors”);
setNextEvent(event=‘category/edit’,persist=“category”);
}

}

I guess my question is what here gets moved into the service layer save method? Validation is usually done at the controller so if you are going to validate here you need to populate your model here. What changes would you make to this?

Dan

Actually I do as much work away from my controller as humanly possible, and I do that in my service.

Regards,

Andrew Scott

http://www.andyscott.id.au/

So should I pass the request collection to my service and basically put that same logic in there ?

That is what I do, pass the entire event in.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Just posing a question because I have often wondered, but what is everyone's thoughts on passing an event object off to the model in MVC? Seemed to me that then my model is to tightly coupled to my implementation of a specific framework, so I have always tried to just pass off only the items I needed to do my specific work instead of passing in the full even object. However, in my approach I have also felt like this was causing me to do more work in my controller objects then I should be. Like in Dan's, checking validation, etc. Probably a question with no "right" answer, but just curious about others musings on the subject.

Thanks,
Curt Gratz

Curt,

I think I have to agree with you. I've played with this concept a few times in the past but found that handling the event stuff inside the model couples things far too tightly.

I try to sanitise / extract values from the event inside the controller before passing them into the model.

Robert

Actually I find it the very opposite, because it creates code reuses as
well.

Let's take a look at authentication for a minute, on a hypothetical blog
application. There are two forms of authentication, both go through a
handler one is restAPI and the other is via a standard login form.

Now I could write to handlers, well I do need too. But instead of writing
the same code twice to send and check that the vars are in the RC, I pass it
onto a service that does this check for me. The service becomes reusable in
this scenario, because I have ended up reducing the code that both the
handlers would have had to write.

This is my logic, and I find that it doesn't couple it that tight.

Regards,
Andrew Scott
http://www.andyscott.id.au/

From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com] On
Behalf Of Robert Rawlins
Sent: Friday, 8 April 2011 12:04 AM
To: coldbox@googlegroups.com
Subject: Re: [coldbox:9248] Refactoring Save Method

Curt,

I think I have to agree with you. I've played with this concept a few

times in

the past but found that handling the event stuff inside the model couples
things far too tightly.

I try to sanitise / extract values from the event inside the controller

before

passing them into the model.

Robert

> Just posing a question because I have often wondered, but what is
everyone's thoughts on passing an event object off to the model in MVC?
Seemed to me that then my model is to tightly coupled to my
implementation of a specific framework, so I have always tried to just

pass

off only the items I needed to do my specific work instead of passing in

the

full even object. However, in my approach I have also felt like this was
causing me to do more work in my controller objects then I should be. Like

in

Dan's, checking validation, etc. Probably a question with no "right"

answer,

but just curious about others musings on the subject.
>
> Thanks,
> Curt Gratz
>
> ________________________________
>
> From: coldbox@googlegroups.com on behalf of Andrew Scott
> Sent: Thu 4/7/2011 8:12 AM
> To: coldbox@googlegroups.com
> Subject: RE: RE: [coldbox:9244] Refactoring Save Method
>
>
>
> That is what I do, pass the entire event in.
>
>
>
>
>
> Regards,
>
> Andrew Scott
>
> http://www.andyscott.id.au/
>
>
>
>
>
>
>
> From: coldbox@googlegroups.com [mailto:coldbox@googlegroups.com]
On
> Behalf Of Dan Vega
> Sent: Thursday, 7 April 2011 10:54 PM
> To: coldbox@googlegroups.com
> Subject: Re: RE: [coldbox:9244] Refactoring Save Method
>
>
>
> So should I pass the request collection to my service and basically put

that

Good use case. I have done the same thing, but have each call one common even using runEvent() to share any common checking, etc. But I can see this as maybe a "better" way to do it.

Curt