[rspec-users] Nosy controller specs

Andrew Premdas apremdas at gmail.com
Thu Dec 11 23:48:46 EST 2008


2008/12/11 Pat Maddox <pergesu at gmail.com> writes

> "Andrew Premdas" <apremdas at gmail.com> writes:
>
> > Pat,
> >
> > Thanks for reply. The one year ago thing was a really bad
> > example. Using your terminilogy it looks like a rule that changes what
> > my app does. But I was talking about a change in what the app is;
> > i.e. a business rule.
> >
> > I definitely don't want to have business rules in controllers. From my
> > viewpoint in MVC the controller is a conduit that allows the business
> > domain encapsulated by the model to be presented in views and in
> > reverse allows interaction with views to communicate with the
> > model. In Rails though its very easy for the business domain to creep
> > into the controller. I'm beggining to think that Rails got this
> > wrong. Perhaps it should have specified a restrictive api between the
> > model and the controller, I've been thinking of something like
> >
> >   get_collection
> >   get_object
> >   get_new_object
>
> You do.... find(:all), find(id) and new(attributes)
>
>
> > By giving completely open access to anything in the model including
> > all classes its real easy for controllers to get real messy. I think
> > the emergence of Presenters as well as skinny controllers is
> > symptomatic of that problem
>
> Oh.  I'm a software libertarian.  Arguments for locking stuff down are
> NEVER going to fly with me.
>
> Look, Ruby is a very powerful language.  As Spiderman teaches us, with
> great power comes great responsibility.  Just because stuff can get
> messy doesn't mean we need to lock down the language or framework.  It
> means we need to be good developers, inventing useful conventions and
> abstractions.
>

I'm looking to find better conventions (for me) to use the power of rails
responsibly. But probably I'm betraying my Java/C++ heritage by using the
word rules instead of convention

In the design of any web framework and in Rails lots of rules/conventions
exist about what you can do and where you can do things. For example Rails
is quite happy to restrict what you can access in views by default.

>
> Do you know the secret to having a clean controller?  Don't write one!
> Use something like make_resourceful.
>
> Thats exactly what I'm looking at. The trouble with these is that the how
of object retrieval ends up buried in 'magic' code somewhere, so when you
need to change things you end up having to overload something somewhat
obscure in the controller, and then having to test this overloading occurs
in a controller spec. For example using resource_controller and the example
below I'd end up with something like

class ProductsController < ResourceController::Base
  private
    def collection
      @collection ||=
end_of_association_chain.find_tagged_with('refill', :exclude =>
'refill')
    end
  end
end

This sort of code isn't very intuitive and (for me) it feels as though its
in the wrong place

>
> > I'll try and give a better example. In my business domain I have
> > products and some of these products have refills which are also
> > products.  Generally when I want to look at all products I don't want
> > to see the refills. This is because the refills are bought and
> > specified through their product. So using tags when I want to find
> > 'all' products I'll actually do the following bizzarre thing
> >
> >    Product.find_tagged_with('refill', :exclude => 'refill')
> >
> > Now generally in Rails this will be done in my controllers index
> > method, and with rspecs scaffold code we'd mock Product and test that
> > this method was called the correct way. So as my call has changed from
> > Product.find(:all) to this new call I have to change my controller
> > spec.
>
> Well, yeah.  You're asking for a different thing now.  You need to
> verify that somehow.  Either you use mock objects to expect a different
> method call, or you write an expectation that you should see one product
> and not another.
>
>
> > Now changing what all products means has nothing to do with
> > controllers and everything to do with models. What my controller
> > should have done is called Product.get_collection. Then when I change
> > my definition of what get_collection does then yes I have to update my
> > model spec, but that makes sense, and my controller and its specs
> > remain the same.
>
> If you really, really want that, why not just change Product.find(:all)
> to return something different?  Same thing.  I don't like it, but same
> thing :)


Because I don't like it either its really ugly, and its far to clever for me


>
> I think you're overlooking the fact that all of this stuff must occur in
> context.  As in "show me all the products" is a straightforward
> statement, yes, but is missing some info.  As you yourself have stated,
> "all" can mean something different than "every single record which
> exists in our system."  The clearest way to represent these contextual
> differences, in my experience, is to create an intention-revealing
> method and use that.
>

The point I'm making is that this intention should be expressed clearly in
the model, whereas currently its expressed in the controller.


> Pat
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users
>

Thanks for providing lots of input, its been most interesting

Andrew
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081212/2ff439ad/attachment-0001.html>


More information about the rspec-users mailing list