Personally I think that things like file uploads, unit conversion
(i.e. Fahrenheit to Celsius), validation and other things that aren't
model concerns, but are still required by the application, belong in
the service layer. In fact I would go so far as to say that this is
the ideal situation for a SERVICE to actually fit its description. The
term "service" implies action, something that provides functionality
that you don't have yourself. A diaper service, an auto repair
service, a file upload handling service, a shipping service... things
that don't help describe the business rules of the domain but are
required for the full functionality of the application to come to
fruition.
This becomes especially obvious if you think of CF tags as services,
especially the ones with action="" attributes that have several
options, as services themselves. An FTP service makes sense because it
handles all the FTP operations for an application. A mail service
makes a great deal of sense and analogizes 1:1 to real-world
"services" (i.e. USPS and FedEx) that we use every day. Yet another
example is the ColdFuson indexing and search service which even gets
installed separately and runs _as a service_ on a machine that
processes requests _for that service_. I don't think you could
possibly find more appropriate examples of what a "service layer"
should do.
Consider also the fact that the file upload itself is purely a
function of the webserver and CF and that you're not really processing
an "upload" but, essentially, a copy operation from the temp directory
to a permanent location. The server takes care of receiving the data
from the HTTP header and turning it into a file on disk. I don't see
this being a framework-level operation any more than logging a user
into a website is. There is, however, a solution to this problem
that's been part of MG for years and would pretty much satisfy the
needs and objections of everyone.
I wouldn't mind seeing an actionpack to do this, but adding it into
the framework is pretty much a complete departure from the charter of
Model-Glue (which is to provide a connection between HTML pages and a
model). Even more so when you start talking about convention-based
operations. Model-Glue has, and I hope always will be, configuration-
based (seriously, if you want a convention-based framework, there are
2 really good ones out there). Adding in an actionpack allows this
functionality to be provided so that you could do something like this:
<event-handler name="files.upload">
<broadcasts>
<message name="uploadFile">
<value name="formField" value="someFooFile" />
<value name="destination" value="c:\someFooPath" />
<!-- add in the other cffile attributes if you want -->
</message>
</broadcasts>
<results>
<result name="success" do="files.goodJob" />
<result name="fail" do="files.youSuck" />
<result name="epicFail" do="files.omgDoYouSuck" />
</results>
</event-handler>
Then again, you don't really need an actionpack to make that work, and
you could, if you wanted, stuff all that crap in the controller. Or
you could build a nice, abstracted FileService that any OO app could
use and have the controller lean on that to do the heavy lifting
(which is the relationship that controllers and services are supposed
to have in the first place). Either way, it would work.
And, as always, keep in mind that it's all opinion and nobody is ever
right, they're just less wrong sometimes. ;)
J
On Oct 16, 2009, at 9:47 AM 10/16/09, Bob Silverberg wrote:
> I was just having an interesting conversation with John Whish about
> where we think file uploads should occur in an OO application. We
> are both processing our file uploads using a Filesystem object
> (FSO), which we both agree should be responsible for doing the
> actual uploads, and simply returning data about the upload to the
> caller (e.g., success, filename, etc). ...
Then again, you don't really need an actionpack to make that work, and
you could, if you wanted, stuff all that crap in the controller. Or
you could build a nice, abstracted FileService that any OO app could
use and have the controller lean on that to do the heavy lifting
(which is the relationship that controllers and services are supposed
to have in the first place). Either way, it would work.
So yeah, I guess we're in less disagreement than I thought. :)
J
It seems that we all share a similar philosophy on this. Hope you guys
can meet up at CFinNC. I'd be interested to see how this progresses.
:)
- John
Bob,I like, and use something along the lines of the first method you describe of broadcasting a needFileUpload message with an argument defining the filefield value, although I'm handling the upload directly in the controller rather than in a separate FileUploader component.However I'm not convinced there's a need to go to the lengths you describe to handle file uploads automatically. This just sounds like an actionpack to me. Surely all thats needed is a controller with a method to detect uploads, handle them (possibly using supporting cfc's like an UploadDetector or FileUploader) then set the metadata into the event, which is fired onRequestStart.Chris
That is a very good idea. Honestly, I haven't used MG much in quite awhile. Although I poke my nose into the framework code every now and then I am kinda rusty from a user perspective. I didn't even think about simply using onRequestStart to do this - duh. I think that would accomplish just what I'm talking about, and different actionpacks could be made available with different implementations. I suppose the only advantage to baking it into the framework would be that developers wouldn't need to locate and install an actionpack as a separate step. Is there some sort of repository for MG actionpacks?
Long ago, in a far away land, I helped someone hack up the RIAForge
code for use as a framework actionpack type deal.
I cannot even remember for whom I was providing help, nor the URL, currently.
Anyways, I've got a metric crapload of actionpacks that are being used
with Gesture. Just none of the ones that came with it.
Dunno if anyone would really find them that interesting, they're
nothing special. The ones that are actually useful in the lot are
things like G11n, exception handling, and maybe the SVN or jExcelAPI
ones.
Eh.
As for convention for file uploads... well, it's fine, but I'll be
honest, and say that anything that does uploading out o' the box
scares the bigeeziz outta me. At least if it's enabled by default.
You have no idea how many times I said on the FCKEditor forums we
shouldn't be shipping the connectors all in there like that... I
mean, it was like, at least twice. :)p
--
Great persecutors are recruited among martyrs whose heads haven't been cut off.
Emile M. Cioran
As for convention for file uploads... well, it's fine, but I'll behonest, and say that anything that does uploading out o' the box
scares the bigeeziz outta me. At least if it's enabled by default.
You gotta know I'm teasing, yeah? Seriously...
Anyway, as for a respository, AFAIK the only repository of actionpacks
is in the Model-Glue SVN repo at http://svn.model-glue.com/trunk/modelglueactionpacks
if that's what you're looking for. Other than that there aren't
really any other sites that have an actionpack library. My suggestion?
Start putting MG actionpacks on RIAForge.
And, redundantly and for the record, my opinion is that Model-Glue is
a configuration-based framework and there are plenty of convention-
based frameworks out there. I think that deliberately adding
exceptional cases to anything is as bad an idea as there is, and that
one broadcast isn't an intolerable quantity of work. While I
understand the arguments for it, I would dispute the notion that it's
actually less work in a big-picture analysis and I would only support
a configuration-based solution if one were ever to be provided as an
actionpack. MG's vision has never been to supply ancillary services
like this except thru the actionpack API and I don't think there's any
reason to distract the team with things that don't apply to the
framework's vision.
In the end, someone who knows MG comes to an MG application expecting
to follow the application execution path thru the config file. If I
were to end up supporting an app where someone added something like
this convention-based approach to file uploads I'd be... umm...
well... OK, to be honest? Pissed. Why? Because it totally defeats the
shining truth that is Model-Glue: consistent, self-documenting,
obviated application operation and architecture. Hiding things in
oRS() just makes application support more difficult.
All opinions expressed here are solely the property of the expresser
and not to be taken in any other way. :)
J
Now this is what I'd call an actionpack! Takes care of the repetitive
drudgery of coding the stuff up for each application handily.
Set a few variables-- wham-bam-thank-you-ma'am!
> On the actionpack front, why not just suggest that people upload actionpacks
> to RIAForge, and make sure that they have MG:ActionPack (or some such) in
> the name. Then the MG team can advertise that fact and people will be able
> to find them.
Yes, I reckon we're in agreement on this front. I really liked the
idea of frameworkforge (IIRC), as we were going to aim at supporting
multiple frameworks, yadda yadda.
To be useful, I think my stuff would need a bit of refactoring, as
well as testing on ACF, as I'm Railo to the hilt.
RIAForge it is tho!
--
In every man sleeps a prophet, and when he wakes there is a little
more evil in the world.
Emile M. Cioran
That is to say: If we're going to do this let's put a bit of planning
into it and not start scattering stuff around. :)
J
MG already has an SVN repository and that SVN repository has an
actionpacks section, so I really dislike the idea of creating yet
another (non-) authoritative container for MG-related stuffages.
I think Mark Drew was working on an MG3 "dashboard" type of deal...
I've been going nuts with Railo's extension stuff (easy way to install code)...
Maybe we could do something similar with the dashboard? Just point it
at location X to get a list of actionpacks, pick one, and then fire
off some type of install process?
That way we're not locking wanna-be actionpack coders into the actual
MG release cycle deal... plus, being concerned about what code you put
on your box isn't a bad thing... er--
I'd typed this up before Dennis sent his git stuff, so um, yeah.
--
Our first intuitions are the true ones.
Emile M. Cioran
I sent MD a message, asking for the code he'd done, as I was going to
make something similar to a dashboard for my super-duper code
generation stuff.
--
Reason is a whore, surviving by simulation, versatility, and shamelessness.
Emile M. Cioran
Hi,
I was wondering if the code for this was ever implemented into MG?
I had developed something similar about a year ago for a MG2 application. I had a generic controller function that would handle uploading and validating files. From this discussion, it seems that putting it inside a service may have made more sense.
While it worked ok for simple files, things got complicated when uploading images. For example, certain images would require to be stored in 3 different sizes. Others would need their corners rounded. I got it to work by adding extra controller functions, but that didn't feel right at all - the image processing should be within the model.
I'd be interested to hear how other people do this?
In particular, I like the sound of File System Objects that encapsulate the file handling. Are there any blog posts/sample code for these, or are they easy enough to build?
Thanks,
Gareth
From:
model...@googlegroups.com [mailto:model...@googlegroups.com] On Behalf
Of Bob Silverberg
Sent: 16 October 2009 15:47
To: model...@googlegroups.com
Cc: John Whish
Subject: [Model-Glue] Who should upload files?
I was just having an interesting conversation with John
Whish about where we think file uploads should occur in an OO
application. We are both processing our file uploads using a Filesystem
object (FSO), which we both agree should be responsible for doing the actual
uploads, and simply returning data about the upload to the caller (e.g.,
success, filename, etc).
We are also both currently call that FSO from a Service. We were
discussing whether to move that logic into the Business Objects (BOs)
themselves. I tend to try to keep my services dumb, and to push logic
into the BOs whenever possible, so this seemed like a candidate, but then we
discussed the fact that the BO shouldn't need to know that a file upload has to
occur at all. Maybe one day the file won't be uploaded, maybe it will
come from another source altogether. So we decided that the BO shouldn't know
about the file upload, and therefore shouldn't be responsible for asking the
FSO to do the upload, so that brings us back to the service.
But then we discussed the fact that the file upload isn't really a model
concern at all. That the model should be independent of the client that's
calling it. So really the service shouldn't need to know that a file has to be
uploaded either. So that leaves the controller. Again, we try to keep our
controllers reasonably dumb and lean, so although this seemed to be the place
to do it in theory, we didn't like the idea of having to add a bunch of code
into each controller method that involved a file upload.
So, by now you're probably wondering, why the heck is he writing this to the
Model-Glue group. Well, we figured that the job of uploading files really
belongs in the controller, and the controller is an extension of the MVC
framework, so maybe this really should be the job of the MVC framework.
The implementation that we imagine would involve convention, and would basically
be something along the lines of:
1. Framework receives request.
2. Framework takes input data (i.e., form and url scope) and puts them into
event object.
3. Framework looks for files to be uploaded - could be done via a convention on
naming of form fields (or maybe it's possible to look at the content of a form
field to determine if it contains a file?)
4. Framework attempts to upload said files and places metadata about the
uploads (e.g., success, filename, etc) into the event object
5. Framework then passes control to the controller for the event, which now has
access to all of the data, and the files are already uploaded.
Of course this isn't a simple matter. What happens, for example, if one
of the uploads fails? Also, it might be nice if this could somehow be a
separate component that could be injected into the request lifecycle, rather
than adding it to the core of the framework itself.
So this discussion raises a few questions for John and I:
1. Is it possible to do something like this without touching the core files of
MG? Is there a plugin point for something like this?
2. Is this even a good idea at all? What thoughts do people have about
where this upload should occur?
3. If it is a good idea, what ideas do people have about how to implement
it? Currently our thinking is to base it on convention, so it would
happen automatically.
Thanks for taking the time to read this, and thanks for any thoughts you may
have. Perhaps I'll see some of you tonight/tomorrow in Raleigh.
Cheers,
Bob
--
Bob Silverberg
www.silverwareconsulting.com
--~--~---------~--~----~------------~-------~--~----~
Model-Glue Sites:
Home Page: http://www.model-glue.com
Documentation: http://docs.model-glue.com
Bug Tracker: http://bugs.model-glue.com
Blog: http://www.model-glue.com/blog
You received this message because you are
subscribed to the Google
Groups "model-glue" group.
To post to this group, send email to model...@googlegroups.com
To unsubscribe from this group, send email to
model-glue+...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/model-glue?hl=en
-~----------~----~----~----~------~----~------~--~---