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