Decoupling the View from the Model

Hi,

In my views I often find myself doing:

<%= user.login %>

These get scattered all over the application. Now imagine I change the
user’s login to name. What happens? It blows in my face. Sure tests can
catch it, but writing tests for that purpose is too painful.

So what kind of tips / ideas / idioms / Design Patterns / other? do you
use to truly decouple the View from the Model.

One should never access object’s attributes like this in the view, and
yet we see this in almost all tutorials, books and what have you. It’s
now hard for me to get rid of that bad habit, and I don’t even know how.

Fernando P. wrote:

Hi,

In my views I often find myself doing:

<%= user.login %>

These get scattered all over the application. Now imagine I change the
user’s login to name. What happens? It blows in my face.

No. Remember that user.login is not an instance variable accessor, even
though it looks like one. It’s a method call.
So if you really wanted to, you could do
class User
def login
@name
end
end

Sure tests can
catch it, but writing tests for that purpose is too painful.

You’re not writing tests “for that purpose”. Rather, you write tests
that exercise as much of your code as possible, then let them tell you
when things break.

[…]

One should never access object’s attributes like this in the view,

Says who? Again, this is not really getting the model object’s
attributes – rather, it’s calling a method on the model object.
Whether the object happens to have an instance variable with the same
name as the method makes no difference to the view and is an irrelevant
implementation detail.

and
yet we see this in almost all tutorials, books and what have you.

Because there’s really no other way to do it, short of assigning every
model method call to a separate controller variable – and that’s just
plain silly.

It’s
now hard for me to get rid of that bad habit, and I don’t even know how.

Because of Ruby’s complete hiding of instance variables, I think it’s
not a bad habit. Don’t worry about it.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

On Wednesday 17 June 2009, Fernando P. wrote:

There is also another idea using a kind of Presenter Pattern, but I
didn’t get it right.

Jay Fields has written some articles on his blog about using the
Presenter Pattern with Rails

http://blog.jayfields.com/2006/09/rails-model-view-controller-
presenter.html

Michael


Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/

On Wednesday 17 June 2009, Fernando P. wrote:

instead of 100 different places.
That would be a job for either helper methods or partials.

Michael


Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/

Because there’s really no other way to do it, short of assigning every
model method call to a separate controller variable – and that’s just
plain silly.

No it’s not. One way to fix this headache could be to add 1 more layer
to the MVC that get’s tied to the model and handles the rendering of an
object. Yeah I know view creeps in the model, but it’s in a separate
file to not clutter the true business logic.

Instead of:

<%= user.login %>
<%= user.age %>

We could call:

<%= user.display %>

So that attributes change only in 2 locations (Model and ModelRender)
instead of 100 different places. Does anyone already use such solution?
How does it work out? Is it better or worse than before? I got that idea
for the book Hollub on Patterns. I’m wondering if the 4th layer of MVC
wouldn’t get out of control with 200 methods for each view in the app.

There is also another idea using a kind of Presenter Pattern, but I
didn’t get it right.

Moreover I figured out that most my views look very similar so finding a
solution to abstract the rendering from the object would be super cool,
and that’s where a Presenter could come in handy if used right (I’m not
talking about Django’s AutoAdmin!)

On Tue, Jun 16, 2009 at 5:12 PM, Fernando P.
[email protected] wrote:

One should never access object’s attributes like this in the view, and
yet we see this in almost all tutorials, books and what have you. It’s
now hard for me to get rid of that bad habit, and I don’t even know how.

#!/bin/sh
cd app/views
for file in */*erb; do
cp $file $file.tmp
sed -e “s/user.login/user.name/g” $file.tmp >$file
rm $file.tmp
done


Greg D.
http://destiney.com/

Michael S. wrote:

On Wednesday 17 June 2009, Fernando P. wrote:

instead of 100 different places.
That would be a job for either helper methods or partials.

Michael


Michael S.
mailto:[email protected]
Michael Schürig | Sentenced to making sense

Sorry, I know I’m still very new to rails but I’ve been learning quite a
bit and have worked heavily on helpers this week.

From my understanding, helpers were designed for markup with views. I
don’t see this as being tied to that unless the login box was wrapped in
a particular div style or box that is being called on multiple views.
In this case, then yes, absolutely - helpers would be a good thing to
use.

From what I’ve researched and read, if the helper file contains
non-markup code, it should be moved to the model.

On Wednesday 17 June 2009, Älphä Blüë wrote:

Michael S. wrote:

On Wednesday 17 June 2009, Fernando P. wrote:

instead of 100 different places.

That would be a job for either helper methods or partials.

From my understanding, helpers were designed for markup with views.

Well, the question is about views.

I don’t see this as being tied to that unless the login box was
wrapped in a particular div style or box that is being called on
multiple views. In this case, then yes, absolutely - helpers would be
a good thing to use.

From what I’ve researched and read, if the helper file contains
non-markup code, it should be moved to the model.

If that was the case there ought to be some good reason for it. I don’t
see any. Go ahead and use helper methods (and presenters, for that
matter) to extract and bundle common functionality. Don’t bother the
model with view concerns.

Michael


Michael S.
mailto:[email protected]
http://www.schuerig.de/michael/