Of ActiveRecord, arel, and train wrecks

I thought that it might be worth starting a discussion about the best
approaches to deal with spec’ing what’s becoming more and more common
in apps using active record.

It started with named scopes, now we have arel, and the old find calls
with parameters are being deprecated.

When I watched Ryan Bate’s latest opus

this morning I decided it might be good to bring my concerns up.

The problem of course is that we’re going to get used to writing more
code like this:

Article.where(“published_at <= ?”, Time.now).includes(:comments)

From one aspect, I find all this very nice. It makes writing queries
easier and much more readable.

On the other hand these are the kind of “train wreck” violations of
the “strong suggestion of Demeter” which makes mocking and stubbing
difficult among other things.

Thoughts?


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

On Feb 22, 2010, at 6:07 PM, Rick DeNatale wrote:

difficult among other things.

Thoughts?

I haven’t spent enough time with it yet to know, but I suspect that
surface mocking (what is usually called stubbing in this community) is
going to get harder with the demeter violations.

OTOH, I guess as there is more structure to a query, it might be easier
to create a more general & dynamic mock library for it - something like
lafcadio’s mocking library or fakefs. With a mocking library like that
out there, we’ll have faster test suites. I’m hoping that it totally
obliviates the need for a library like guillotine
(GitHub - smtlaissezfaire/guillotine: A Ruby SQL Parser).

Scott

On Mon, Feb 22, 2010 at 6:16 PM, Scott T. [email protected]
wrote:

I haven’t spent enough time with it yet to know, but I suspect that surface mocking (what is usually called stubbing in this community) is going to get harder with the demeter violations.

One of the things that I tend to do, is to not use chained scopes in
controllers, but define model methods which use them, which allows for
stubbing/mocking those methods, and keeps the train wrecks isolated.


Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: Rick DeNatale - Developer - IBM | LinkedIn

From a mocking / stubbing perspective, how is this different from
Article.all(:conditions => [‘published_at <= ?’, Time.now], :include =>
:comments)
?

i.e. in both cases wouldn’t you do

class Article
def self.active_published
all :conditions => [‘published_at <= ?’, Time.now], :include =>
:comments
# where(“published_at <= ?”, Time.now).includes(:comments)
end
end

and mock the call to Article.active_published instead?

Pat