[LRUG] Proffer and introducing constraints to Rails

Simon Coffey simon at tribesports.com
Wed Apr 4 07:16:34 PDT 2012


On 2 April 2012 21:55, Andrew Premdas <apremdas at gmail.com> wrote:
> The problem that proffer addresses isn't the important problem IMO.
> The problem is that with Rails it is so easy to get powerful objects
> without constraints into views where they can be abused.

While the problem you describe is certainly another thing that could
use addressing, I'm not sure I agree that ubiquitous global view state
is a minor problem. I'm just going to climb on this hobby horse for a
second... :-)

As a method of transferring data to the top-level template, instance
variables are sort of tolerable-ish, but as soon as they start being
accessed from within partials or helpers - anything that's not tied to
the specific controller action in which they're set, really - you're
creating a maintenance timebomb.

View code reuse becomes a drag, because to reuse something that
accesses an ivar you've got to find its original use, and follow all
the way back up to the controller action where it was set*, then
replicate that ivar in the new context. Code starts getting
cargo-culted between controller actions, because it's frequently
easier to do that than precisely determine which set of ivars a
particular render is going to need.

Changing things is even worse. You remove a partial or helper that
depends on an ivar. Can you safely remove the ivar it depended on? It
could be accessed by any number of other things in the render tree,
and can't be sure without following every possible code path for a
render of that action. So you delete it and hope your tests cover your
shame, or you leave it there and take a performance hit fetching data
that you're not even sure you need.

We've been using a combination of Cells
(http://github.com/apotonick/cells) and decorators to clean this up,
but having an explicit interface between controller and template is
still a missing link, and it's nice to see this problem tackled.

Cheers,
Simon

*or it might be set in a before_filter, or a before_filter higher in
the controller's inheritance chain, or (heaven help you) in another
helper called earlier in the render, or even (caution, rated R) in
another template. Global state, eh? Fun.



More information about the Chat mailing list