On Sun, Apr 19, 2009 at 12:24 PM, Mark Wilden <m...@mwilden.com> wrote: > On Sun, Apr 19, 2009 at 3:51 AM, Matt Wynne <m...@mattwynne.net> wrote: > >> @order_presenter.product_titles do |product_title, url| >> <%= link_to product_title, url %> >> end > > The presentation of an order in most apps will be constructed from > additional columns (e.g., color, size, price, extended price). These > columns may well be formatted differently depending on the > circumstance (e.g, printed or on-screen). > > Now, it might be a good idea to put this construction and formatting > in a helper or presenter outside the view (though it won't be > TSTTCPW). But anywhere you put it, there will be non-Demeterian code > that needs to drill down into each order's items', products' > information (as well as non-product information, such as line-item > discount). If the underlying model changes, this code will have to > change - you can't avoid it.
Agreed. I think Dan Manges post is a good one on this topic as well: http://www.dcmanges.com/blog/37 His second to last paragraph: "The crux of this is that webpage views aren't domain objects and can't adhere to the Law of Demeter. Clearly from the examples of behavior delegation the Law of Demeter leads to cleaner code. However, when rendering a view, it's natural and expected that the view needs to branch out into the domain model. Also, anytime something in a view dictates code in models, take caution. Models should define business logic and be able to stand alone from views. If this "train-wreck" method calling in your views is bothersome, there is a better solution that I will blog about later." I tend to agree his thoughts on this, but be careful how you read the sentence "anytime something in a view dictates code in models, take caution". He isn't referring outside-in development practices. He's referring to adding methods in a model for strictly presentation purposes, which is bad because it dilutes the richness of the model, and makes it change for reasons it shouldn't. Here's another article which discusses why methods shouldn't be added to models for presentation purposes: http://spin.atomicobject.com/2008/01/27/the-exceptional-presenter Although if you read that article and want to try out presenters, you should know that CachingPresenter supersedes the PresentationObject library in the article. And you don't need a library to use presenters, your presenters can be POROs just like Matt Wynne posted. I tend to like the CachingPresenter library (heck I wrote it) approach so I can utilize caching, memoization, and a slightly more declarative API and list of helper methods. One technique I've employed in the past along side presenters (although it can be done w/o presenters) is to make use of partials, and actually treat them like little view objects. So you could take what you had: @order.items.each do |item| item.product.title end And transform it into two views, one that is concerned with the order, and a partial which is concerned with the product of an item. : <%= render :partial "items/product", :collection => @order.items.map(&:product) %> And then add a "items/product" partial and spec it in isolation. Spec'ing views (and partials) in isolation gives you the ability to have simpler view specs, and you're able to avoid feeling the awkward need to build up a network of objects. And you don't have to worry about adding a bunch of little delegate methods all over the place. -- Zach Dennis http://www.continuousthinking.com http://www.mutuallyhuman.com _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users