Powered By BlogNow - Get Your Free Blog

I have moved!

My new blog is at lindsaar.net

All the old content will stay here though. But check out the new blog

¿ 22/7/2007 - Reflect on association one liner to check association details

Evgeny asked me about my reflect_on_association post to find out if a one liner could be made to check several association values, that is, not just trusting that the association details would be correct.

You can't do it in a one liner, but this is how to make it as simple and DRY as possible for testing on multiple models.

First off, Class.reflect_on_association returns something akin to a hash, but not a hash.  It actually returns an object of type ActiveRecord::Reflection::AssociationReflection

So, to test this, we need to get the data into a usable form.

This is done through a helper method in spec_helper.rb (if you are using RSpec.

I used this:

  module ActiveRecord
module Reflection
class AssociationReflection
def to_hash
{
:macro => @macro,
:options => @options,
:class_name => @class_name || @name.to_s.singularize.camelize
 }
end
end
end
end


Then, in the spec you are testing, you can do:

  it "should test reflection details" do

association_results = {
:macro => :belongs_to,
:options => {:counter_cache => :true},
:class_name => "Location"
}

User.reflect_on_association(:location).to_hash.should == association_results

end


You can then use this method in any spec you want.

So, there you go Evgeny... not quite a one liner, but a lot easier to read!

blogLater

Mikel
Post A Comment! :: Send to a Friend!

¿ 22/7/2007 - Sweeet!!!

Posted by Evgeny
This looks beautiful!

But, any way to make this even prettier with the use of
"with_options"? (since we are dealing with hashes anyway)
Permanent Link

¿ 22/7/2007 - with_options?

Posted by mikel
Sure you could.

But what are you trying to achieve?

Maybe you can tell me, I can point you in the right direction and you can nut it out... I'll help you if you get stuck :)

Mikel
Permanent Link

¿ 23/7/2007 - Re: with_options?

Posted by Evgeny
Trying to find the best way to achieve a good rspec. since I am constantly thinking that I want to have a repository of really good specs that really check your stuff well.

For example, what you posted on your previous post :
Model.reflect_on_association(:association_model_name).should_not be_nil

It doesn't really check much, just that an association exists. And if you put a bunch of these together - like 6 for a user model, then you don't really know why they are there.

Now - a year later you edit the user model, and remove the counter_cache for example. You won't even notice a difference in the specs.

On the other hand, if you have counter_cache specified as well as the association - then you have a pretty good description of what it is and why it is there. The spec name.

If I am investing such a large amount of time in specs, I want them to really tell me whats going on when I no longer remember the code of the user model. So when something breaks or doesn't work, I won't miss it. Examples of things that may break is DB software version, Rails version, Rails plugin versions, etc ...

Too many times I spent days debugging a problem with no clue where it landed on me.

But on the other hand, if the spec is too long and not "beautiful", I won't remember it later on - and will want to re-invent the wheel.

to sum it up just in a word or two, "I guess I am a perfectionist of a sort." :)
Permanent Link

¿ 23/7/2007 - To Spec or not to Spec

Posted by mikel
Well, in my opinion, a spec is a spec when it fully specifies the application under development.

You might want to consider looking at Heckle. It is a program that modifies your code to see if your specs provide as much coverage as you expect.

Providing specs for what this brings up should cover you fairly well.

But again, spec what you write is a good maxim.

blogLater

Mikel
Permanent Link

¿ 23/7/2007 - Untitled Comment

Posted by Evgeny
Ohh, and I forgot to mention. I want to have as much "coverage" (with rcov) as possible. So even when rcov shows 100% coverage, that still might be lacking in the actual coverage.
Permanent Link

¿ 27/7/2007 - Untitled Comment

Posted by Anonymous
I found that this gave problems when running with autotest, although all was fine using rake spec.

The problem was with the class_name in the to_hash method. If I included a spec as you outlined in my test suite (with the code you suggested in spec_helper) and set autotest off on its merry way then on the first pass all is fine. If I then make an edit to the file containing the spec (say to the text in the 'it' bit it was failing the second time around on the :class_name part of the hash.

Changing the class name assignment to:

:class_name => @class_name || @name.to_s.singularize.camelize

fixes this. No idea why this happens mind you!

Cheers

Rupert
Permanent Link

¿ 27/7/2007 - Class name fix

Posted by mikel
Thanks Rupert,

I updated the code above (I found the same error).

Mikel
Permanent Link

¿ 29/7/2007 - Untitled Comment

Posted by Anonymous
no prob at all

...although it should be in the AssociationReflection. to_hash method in spec_helper, not in the spec itself (well, that's where I put it anyway)

Thanks for the post btw - found it very useful

Cheers

Rupert
Permanent Link

¿ 29/7/2007 - Oops...

Posted by mikel
stupid copy paste error. The above is now correct, thanks Rupert.
Permanent Link

¿ 10/8/2007 - RSpec Matcher

Posted by Steve Tooke
Mikel great couple of posts.

I've wrapped your solution up into an RSpec custom expectation matcher: http://stevetooke.karmatrading.co.uk/2007/8/10/simple-rails-association-matching-with-rspec
Permanent Link

¿ 8/9/2007 - :class_name =>

Posted by Anonymous
If I have belongs_to author, :class_name => person, foreign_key => author_id....

It seems the reflection's hash has class_name => Author and options =>{:class_name =>Person, :foreign_key=> author_id}

You code naturally checks against the unnested and bizarre :class_name => Author....and doesn't behave as expected.

still trying to work out why...
Permanent Link

¿ 9/9/2007 - Replies

Posted by mikel
@steve, Thanks!
@anonymous - could you show a bit more of your code... not quite sure what you mean here. Perhaps paste a link to a pastie...

Mikel
Permanent Link

About Me

AKA Raasdnil, this site is about web coding, hosting and all other matters that relate to this... especially Ruby on Rails!

Links