where to put view logic

8 views
Skip to first unread message

Wes James

unread,
Nov 17, 2008, 4:16:27 PM11/17/08
to web2py Web Framework
Is the best place to create data for views in the controller. For
instance, after a student enters some initial data, I need to look at
that data and determine what scholarships they might be eligible for.
Along with the student data and a scholarship table, I need to do a
bunch of "if then" logic. Would I put that in the controller?

For instance, the student is a female, in such and such major and is a
senior. For each scholarship I must then look at the DB and determine
the requirements and if they are eligible, tack that Scholarship name
in to: response.schols += "<li>This Scholarshiip</li>" and then do
respons.total += db.scholarship_amount. And then in my form do:

<output>
You are eligible for these scholarships:

{{=response.schols}}

You could receive as much as ${{response.total}} for the school year.
</output>


Is this correct?

thx,

-wj

Timothy Farrell

unread,
Nov 17, 2008, 4:24:35 PM11/17/08
to web...@googlegroups.com
You're almost there.

Yes, put all of the if/then logic in the controller, that what controllers are made for.

The purpose of MVC separation is make the View and Controller completely abstracted pieces.

Ideally, doing any HTML work in the controller is an MVC violation.  Instead you should pass a list of strings (of scholarships in this case) to your view.  Like so:
schols = []
schols.append('Random Free Money')

return dict(schols = schols)

And then in your view, loop over the list with the appropriate markup.

-tim
-- 
Timothy Farrell <tfar...@swgen.com>
Computer Guy
Statewide General Insurance Agency (www.swgen.com)

Yarko Tymciurak

unread,
Nov 17, 2008, 6:15:28 PM11/17/08
to web...@googlegroups.com
And the purpose of separation is to prevent "unnatural design coupling."   Some things may be "naturally coupled" across layers, such as a login.  But what about student name?  Student name is part of the data structure, used in logic, and presented in a friendly way...    What if, at the data level, you decide to change - and store student name as "given_name / family_name".  If controller hides that detail, then presentation doesn't need to know, and you are free to modify your data structure (perhaps to meet other new requirements) without the "ripple" (need for changes in many places) effect of inappropriate design coupling.

That, essentially, is the point of MVC.

A way I like to think of MVC - rename it logically - is:

DATA Layer (a.k.a. model) - has to do with data design, and details of persisting data (table specific stuff; stuff for getting things out of / into database,   constraints that have been designed to be in the persisted data, etc.);

LOGIC (a.k.a. controller(s)) - all the stuff you've (correctly) described as application logic - the guts of your solution's behavior; this includes some level of preparation of forms (that is - setting up the interface for what will be accepted as input to the application);

PRESENTATION (a.k.a. view) - things that have to do with grabbing data to display, wrapping it in presentation-like things (divs), and things you've decided to run at the client.

Think of these as literal layers - a stack, e.g. view should never access / assume / know about anything in the model, even if it "seems silly not to" - it will create a coupling that will create brittleness, and could bite you badly later.

Presentation has to get stuff from logic, and present things to it;  

logic has to validate, combine, and choose things to store, and give things to be presented (like a consistent "student name");   

data has to connect w/ the physical data store, ensure that the stored items meet constraints, are consistent with the storage type, etc.

They have (and set up) interfaces between each other.  They should access each other only in their interfaces (in what they choose / need to expose).

Yes, you put application logic in the controller - but literally, there is logic in each of these layers, it is concerned with different aspects of the application.   Sometimes I fear I harp on this too much, but it is fundamental.

Kind regards,
Yarko

billf

unread,
Nov 18, 2008, 11:41:58 AM11/18/08
to web2py Web Framework
Yarko

Basically I agree with everything you say. There are always going to
be some grey areas but that's life.

For example, I could argue that hiding changes to the model could be
handled by the model (as opposed to the controller as you suggest) by
exposing a "legacy" view. (I'm talking generally rather than just
web2py).

Also, you say the controller/logic includes "setting up the
interface". It depends what you mean. If you mean collating the data
required by the interface then I agree. If you mean defining some
aspects of the presentation of the interface then I don't agree.

I am currently finishing coding and testing an extension (for want of
a better word) to web2py that, I believe, supports most of your
requirements. As soon as it is robust, I will post the files.
> > Timothy Farrell <tfarr...@swgen.com> <tfarr...@swgen.com>
> > Computer Guy
> > Statewide General Insurance Agency (www.swgen.com)- Hide quoted text -
>
> - Show quoted text -

yarko

unread,
Nov 18, 2008, 1:04:41 PM11/18/08
to web2py Web Framework

On Nov 18, 10:41 am, billf <billferr...@blueyonder.co.uk> wrote:
> Yarko
>
> Basically I agree with everything you say.  There are always going to
> be some grey areas but that's life.
>
> For example, I could argue that hiding changes to the model could be
> handled by the model (as opposed to the controller as you suggest) by
> exposing a "legacy" view. (I'm talking generally rather than just
> web2py).

Yes.... at some level.... at another level, the view should know
nothing about the model.

In the simple case, this decays to something looking like this:

view: index.html:

{{ =person }}

controlller: default.html::index()

...
person = SQLFORM( db.person)


and SQLFORM is the utility function that operates as the controller
interface to the data layer.

>
> Also, you say the controller/logic includes "setting up the
> interface".  It depends what you mean.

by interface, I mean the traditional programming meaning: the
classes, functions and attributes that are intended to be accessed by
the views.

>  If you mean collating the data
> required by the interface then I agree.  If you mean defining some
> aspects of thepresentationof the interface then I don't agree.

I'm not sure what you mean - presentation and programming interfaces
are somewhat separate things...

Regards,
Yarko

Yarko Tymciurak

unread,
Nov 18, 2008, 1:22:25 PM11/18/08
to web2py Web Framework
.... 

In the simple case, this decays to something looking like this:

view:  index.html:

{{ =person }}

controlller:  default.html::index()

I meant derault.py::index()

billf

unread,
Nov 18, 2008, 3:03:07 PM11/18/08
to web2py Web Framework
Responses below

On Nov 18, 6:04 pm, yarko <yark...@gmail.com> wrote:
> On Nov 18, 10:41 am, billf <billferr...@blueyonder.co.uk> wrote:
>
> > Yarko
>
> > Basically I agree with everything you say.  There are always going to
> > be some grey areas but that's life.
>
> > For example, I could argue that hiding changes to the model could be
> > handled by the model (as opposed to the controller as you suggest) by
> > exposing a "legacy" view. (I'm talking generally rather than just
> > web2py).
>
> Yes....  at some level.... at another level, the view should know
> nothing about the model.

I'm not saying that the (presentation) view knows anything about the
model just that the change to the model could be catered for by a
(database/model) view, i.e. even the controller might not need to know
that the persistence model has changed.

>
> In the simple case, this decays to something looking like this:
>
> view:  index.html:
>
> {{ =person }}
>
> controlller:  default.html::index()
>
> ...
> person = SQLFORM( db.person)
>
> and SQLFORM is the utility function that operates as the controller
> interface to the data layer.
>

Assuming you are referring to the current SQLFORM, this seems to me
the key area for debate. An SQLFORM is created by the controller and
pre-determines what the view can do, i.e. it creates an html form.
Until the recent patch, the view couldn't even extract the current
value of a field without navigating through a tree of html helpers. I
agree that something must act as the bridge between the view and the
model, I just think that SQLFORM is not the way to do it.

My approach is to use a class (Resource) to act as the bridge between
view and data. The resource is constructed by the controller and the
controller can apply constraints, i.e. limit what the view can do but
in a functional not a presentational way. So, for example, the
controller can specify that a resource cannot be deleted but couldn't
say that the view could only output an html form. The controller could
receive an update request without a form being displayed (as web2py
can now) but doesn't have to create an SQLFORM to process that request
- it just creates the resource, updates it with the request and, if
valid, persists it.

>
>
> > Also, you say the controller/logic includes "setting up the
> > interface".  It depends what you mean.
>
> by interface, I mean the traditional programming meaning:  the
> classes, functions and attributes that are intended to be accessed by
> the views.
>
> >  If you mean collating the data
> > required by the interface then I agree.  If you mean defining some
> > aspects of thepresentationof the interface then I don't agree.
>
> I'm not sure what you mean - presentation and programming interfaces
> are somewhat separate things...
>

Too many uses of the word "interface" (as in "user interface", API) -
I agree with you.

> Regards,
> Yarko

Yarko Tymciurak

unread,
Nov 18, 2008, 3:26:05 PM11/18/08
to web...@googlegroups.com

On Tue, Nov 18, 2008 at 2:03 PM, billf <billf...@blueyonder.co.uk> wrote:


I'm not saying that the (presentation) view knows anything about the
model just that the change to the model could be  catered for by a
(database/model) view, i.e. even the controller might not need to know
that the persistence model has changed.

This discussion could easily confuse and decay into non-pertinent perspectives....

I will simply say this way:

The presentation shows what the client / user knows / expects.

The logic / controller level will do application specific things (validation, temporary calculations, etc.), and map the user's view of the data to the designed (persisted) data representation.

The data layer will hide the details of the representation.  At one level, DAL does this for us.  But at another, optimizing data design as your application evolves (or it's scope changes) would be best to limit, not involve change from the controllers.   Design / performance concerns may modify this, but that is a separate topic.


The starting position is that DAL is most of what you need for isolation, so you don't need to worry too much.  And that is a good _starting_ position.




>
> In the simple case, this decays to something looking like this:
>
> view:  index.html:
>
> {{ =person }}
>
> controlller:  default.html::index()
>
> ...
> person = SQLFORM( db.person)
>
> and SQLFORM is the utility function that operates as the controller
> interface to the data layer.
>

Assuming you are referring to the current SQLFORM, this seems to me
the key area for debate.  An SQLFORM is created by the controller and
pre-determines what the view can do, i.e. it creates an html form.
Until the recent patch, the view couldn't even extract the current
value of a field without navigating through a tree of html helpers.  I
agree that something must act as the bridge between the view and the
model, I just think that SQLFORM is not the way to do it.

SQLFORM is a convenience function - a helper;   nothing says the controller has to use it; it's just handy if that's all you need.  You would not be happy if you did NOT have it.
 


My approach is to use a class (Resource) to act as the bridge between
view and data.  The resource is constructed by the controller and the
controller can apply constraints, i.e. limit what the view can do but
in a functional not a presentational way. So, for example, the
controller can specify that a resource cannot be deleted but couldn't
say that the view could only output an html form. The controller could
receive an update request without a form being displayed (as web2py
can now) but doesn't have to create an SQLFORM to process that request
- it just creates the resource, updates it with the request and, if
valid,  persists it.

I think we're mixing design choices with architectural (layer / MVC;  structural!) discussions.  Perhaps it's best to keep these separate.

billf

unread,
Nov 18, 2008, 4:04:43 PM11/18/08
to web2py Web Framework
Re "SQLFORM is a convenience function - a helper; nothing says the
controller
has to use it; it's just handy if that's all you need. You would not
be
happy if you did NOT have it."

Sure, but that doesn't make it a good MVC class. One simple example:
SQLFORM is instantiated in the controller and gets the labels to be
used in the form from one of two places - its constructor or the model
- both of which are bad MVC separation IMHO. My aim in these
discussions is to find a concensus on how to replace these "features".

RE "I think we're mixing design choices with architectural (layer /
MVC;
structural!) discussions. Perhaps it's best to keep these separate."

I don't think I'm mixing design choices with architectural
discussions. But if you think that I am then we probably won't get
much further at this time :-)


- Hide quoted text -

On Nov 18, 8:26 pm, "Yarko Tymciurak" <yark...@gmail.com> wrote:
> > > Yarko- Hide quoted text -
>
> - Show quoted text -- Hide quoted text -

Yarko Tymciurak

unread,
Nov 18, 2008, 4:28:08 PM11/18/08
to web...@googlegroups.com
Making SQLFORM (or anything) "good MVC" isn't the point, I think.

When you need simple, direct data form to user (as admin does), it's a design choice to use this convenience function - in that case, strict MVC is just not of primary importance - basically, we don't care that much (because we don't need to) for admin!  And you do still have separation - it's sufficient for certain cases.

I think a discussion of when to use SQLFORM , and when some alternative might be a better choice (and perhaps how to make SQLFORM more broadly useful without losing it's convenience) is what I'm after.
Reply all
Reply to author
Forward
0 new messages