> From: Bill Moseley [mailto:[EMAIL PROTECTED]] 
> Sent: 08 June 2002 20:48

> I've gone full circle on handling user input.  I used to try to
abstract
> CGI input data into some type of request object that was then passed
onto
> the models.  But then the code to create the request object ended up
> needing to know too much about the model.

> For example, say for a database query the controller can see that
there's a
> query parameter and thus knows to pass the request to the code that
knows
> how to query the database.  That code passes back a results object
which
> then the controller can look at to decide if it should display the
results,
> a "no results" page and/or the query form again.

So in pseudo code-speak, how about something like:

# Note that I am ignoring Exceptions for the sake of dealing with the
# Controller / Model interaction question.

# $param is a ref to an Apache::Table that contains all the user
submitted
# parameters from the request. The main job of cleanupParams() is to do
# things like URDDecode() etc, and marshal all the user input into a
simple
# structure.
my $param = cleanupParams($r);

# Instantiate Model. Pass it ALL user parameters - Model can cherry pick
only
# the ones it is interested in, and ignore the others. Adding new
parameters
# in the preceeding View that gave rise to this request makes no
difference
# to the Controller - only the Model and View needed to change.
my $Model = My::Model->new( %$param );

# And which View should we instantiate? Well, you might choose one in
the 
# Controller, but I only do this if there was a major Model meltdown.
For
# no result searches, the usual search View should be able to handle
things
# with a nice message.



> Now, what happens is that features are added to the query code.  Let's
say
> we get a brilliant idea that search results should be shown a page at
a
> time (or did Amazon patent that?).  So now we want to pass in the
query,
> starting result, and the page size.

As shown above, the Controller doesn't really care about any new
parameters, it passes them all, including new ones through transparently
to the model.

The model I like for paginated results is straight-forward. When the
Model is instantiated, it does NOT find a query_id field in the passed
parameters, so it assumes a brand new query, and returns the first N
results. A brand new, unique query_id is issued, and becomes a property
of the Model. In the paginated View, this query_id is inserted into a
hidden field (or cookied if you prefer). A session is created using the
query_id that contains all of the parameters that the Model considers
important. The paginated View contains First, Last, Next, Prev links
that just call the same URL with an action=>next, last, prev etc.

When the Model is instantiated for a subsequent page, it sees a
query_id, loads all the query details in from the session storage, and
retrieves the appropriate set of records for the this-time-round View.

> What I didn't like about this is I then had to adjust the so-called
> controller code that decoded the user input for my request object to
> include these new features.  But really that data was of only interest
to
> the model.  So a change in the model forced a change in the
controller.

I think covered above? 

> So now I just have been passing in an object which has a param()
method
> (which, lately I've been using a CGI object instead of an
Apache::Request)
> so the model can have full access to all the user input.  It bugs me a
bit
> because it feels like the model now has intimate access to the user
input.

I don't like this either, but probably need a concrete example of
exactly what Request properties you find it necessary to use in your
Model. The way I see it is that the Controller is interested in the gory
details of the Request object, after all it is a Web Controller, but the
Model should only be interested in the parameters. The Controller uses
the Request object context, and sometimes basic parameters to decide
which Model to instantiate, it doesn't care about Model parameter
requirements - the Model must validate itself.


> links back to a page, such as a link for "page next".  I like to build
> links in the view, keeping the HTML out of the model if possible.  But

> for something like a "page next" link that might contain a bunch of 
> parameters it would seem best to build href in the model that knows 
> about all those parameters.

As described above, I like to use a session to store Model state over
multiple executions / pagination of a collection type Model.


Regards
Jeff


Reply via email to