The way I go about this is, IMO, pretty straight forward. I cringe when people start talking about generating html in models, since I think separation of concerns is much more important than law of demeter, and I think that the model most definitely shouldn't be concerned with how it needs to be displayed.

In your original example you have:
@order.items.each do |item|
 item.product.title
end

The way I would do this is:
@order.items.each do |item|
render :partial => "product/line_item", :locals => {:product => item.product}
end

In other words, I might have the following partials:
product/_line_item
product/_product (full representation of product probably for detail page)
product/_search_item (for display in a search result)

etc.

All the partials simply take a product object. There is probably already some smart, intention revealing name, but I call them "nanoformats". I'm not exactly an Academic, so I have no idea the validity of my approach, but this seems to get around the law of demeter enough for me (thought, obviously not totally since order still *technically* knows about order.items.products). Order doesn't actually know anything about products or it's internals, except that it has some. The partial could be reused in other places, and with semantic markup, can be displayed in very different ways with a little CSS. A change to Product only necessitates changes to the app/views/products/* files. Your Orders don't need to know anything, item probably doesn't even need to be updated. the partials can be spec'd independently of wherever they are being used.

Your view and your models are always going to be tightly coupled, and a change in your domain object should probably necessitate a change in your views. That's the way it *should* work. However, your views shouldn't be tightly coupled with each other but they will have to be coupled in some way or another.

-----
BJ Clark



On Apr 19, 2009, at 12:37 PM, Fernando Perez wrote:


  http://spin.atomicobject.com/2008/01/27/the-exceptional-presenter
Interesting idea too. So basically I need to totally rethink and
refactor the way my views display the information to the customer:

Let's see how I currently display or not an add to cart button depending
whether or not the product is free.

My very first quick and very ugly procedural hard to spec solution was
to do in the view:

<%- if @product.price >= 0 -%>
 <%= display_button %>
<%- else -%>
 This product is free!
<%- end -%>

Then my second solution was to create an instance method so that the
view doesn't know about the Product internal mechanism about it's
freeness:

<%- if @product.free? -%>
This product is free!
<%- else ... -%>

Yeah I thought I was an OOP master and Demeter could rest in peace!

But thinking about the GOF Builder and Exceptional Presenter design
patterns you talk about, that would mean that the html output for a
Product should therefore happen in the Model itself. And then in the
show.html.erb, I simply call:
<%= @product.display -%>

and all the magic about whether or not the product is free and to
display the button has already been handled inside the model (or another
related place) when it gets instantiated. Same applies to
item.product.title, that would be handled elsewhere than in the view.

However it might clutter the Model, so actually there is more to MVC:
each Model should have a sub class or something that handles how the
model instance will be presented to the view.

How do you handle such issue? Are there some open source rails apps that
I could learn from?
--
Posted via http://www.ruby-forum.com/.
_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

_______________________________________________
rspec-users mailing list
rspec-users@rubyforge.org
http://rubyforge.org/mailman/listinfo/rspec-users

Reply via email to