RSpecers point of view about how to create rails association

Hi,

Using Ruby on Rails, let’s says I have an Article model and Comment
model. An Article has_many :comments,

Using Rais idiom, one would do something like that in the
comments_controller/create:

@article = Article.find(params[:id])
@article.comments.create(params[:comment])

I don’t like too much this approach because it puts too much
intelligence into the controller and it’s not easy to test/spec/mock.

So I’d like to push this into a model. So would you tell Article model
to create a new Comment given params[:comment], or would you tell
Comment to create a new Comment given an article_id?

From a BDD point of view, only creating a new comment record is what
counts, but I’d like to be more careful about Demeter, encapsulation,
tell don’t ask, …

On May 2, 2009 11:00am, Fernando P. [email protected] wrote:

Hi,

Using Ruby on Rails, let’s says I have an Article model and Comment

model. An Article has_many :comments,

Using Rais idiom, one would do something like that in the

comments_controller/create:

@article = Article.find(params[:id])

@article.comments.create(params[:comment])

I don’t like too much this approach because it puts too much

intelligence into the controller and it’s not easy to test/spec/mock.

So I’d like to push this into a model. So would you tell Article model

to create a new Comment given params[:comment], or would you tell

Comment to create a new Comment given an article_id?

From a BDD point of view, only creating a new comment record is what

counts, but I’d like to be more careful about Demeter, encapsulation,

tell don’t ask, …

These are all good things to consider, but they also need to be weighed
against the design decisions made for us by ActiveRecord. You could
write
wrapper methods for chains like this and make Demeter happy, but to do
that
for every single call you need has a cost too, and the associations are
pretty close to free.

I’ve rolled both ways on different apps - writing wrappers for
everything
and leaving the chains as/is in others. The thing I’ve noticed is that
stubbing one association feels fine to me, but stubbing an association’s
association starts to get painful in the code examples.

Now there is a very good compromise solution in Luke R.'s library
named “Demeter’s Revenge” which basically creates create_comment (and
other
related methods) on the fly for you. This, to me, is an ideal solution
for
a declarative framework like ActiveRecord where you don’t even see the
comments method in the Article class. Should the underlying structure
change, you can always redefine create_comment in the Article class and
all
it’s consumers are happy. The code examples are happy because they need
not
stub chains. And your fingers are happy because you’re not typing out
all
of these wrapper methods.

The only potentially unhappiness is going to come from whomever reads
the
code later and is not familiar with the plugin and wonders where the
hell
that method is being defined.

That’s my 2 cents. Anybody else?

David

Posted via http://www.ruby-forum.com/.


rspec-users mailing list

[email protected]

You could write wrapper methods for chains like this and make Demeter
happy, but to do that for every single call…

Thank you for your experience. I myself used to wrap these kind of
associations but I felt it started to clutter the Model file, so I
started to use association callbacks.

My heart balances between both ideas. Anyway if attr_accessible is used,
then you must write a wrapper, but in other cases? Which is the most
effective / maintainable / etc is still to be questioned.

Honestly, each time something backfired at me in a very unexpected
manner, it was due to the fact that somewhere far far away I had broken
Demeter’s law. So I’d like to get this fixed once and for all.

On Sat, May 2, 2009 at 11:25 AM, [email protected] wrote:

The only potentially unhappiness is going to come from whomever reads the
code later and is not familiar with the plugin and wonders where the hell
that method is being defined.

To whom I’d say “Welcome to Rails.” :slight_smile:

///ark