Tuesday, 18 August 2009

Polymorphic associations make my head hurt

Oh man.
I have an organisation class which has a number of "sub" classes - clients, printers, prospects, suppliers etc. An organisation can have many sub classes (ie an organisation could be simultaneously a client and a supplier for example).
Because clients, printers and prospects are quite different beasts they have to be different classes - not just different instances of the same class - hence the need to have a polymorphic relationship.
Tried to follow Ryan Bates's railscast but it wasn't really working for me.
After playing around with the console to get my head around what is really going on I came up with another way of sorting them out.
Have got the create method to work.
The way I came up with works on the basis that having denoted two classes to have a polymorphic relationship with each other, you can assign an instance of one to the other through the join (and that makes perfect sense ...)
What do I mean by that? Here are the models
class Organisation < ActiveRecord::Base
belongs_to :resource, :polymorphic => true

class Client < ActiveRecord::Base
has_one :organisation, :as => :resource

class Printer < ActiveRecord::Base
has_one :organisation, :as => :resource
if I instantiate an organisation object, o, and a client object, c, then by doing o.resource = c, I get the join I am looking for (sets the resource_id and resource_type) correctly.

My rather kludgy create model uses this:
params[:orgtypes].each do |ot|
@organisation = Organisation.new(params[:organisation])
resource = create_class(OrganisationType.find(ot).name)
resource.save!
@organisation.resource = resource


The create_class method takes a string and returns an instance of that class:
def create_class var
Object.const_get(var).new
end

I have a table of classes in the OrganisationType class - which allows me to add new ones dynamically which was my concern with doing everything hardwired - if I want a new sort of polymorphic thing, I can add one quite easily.
Now to sort out the update method, and to write some proper tests to make sure this sucker works in the way I hope it does.

Friday, 14 August 2009

a sight for sore eyes

Started
................................................................
Finished in 3.983101 seconds.

64 tests, 166 assertions, 0 failures, 0 errors


Unit tests with Factory Girl

Getting the HABTM working was a tricky thing. In the end I had to do this:

def setup
@job = Factory.create(:job)
@version = Factory.build(:version, :job_id =>@job.id)
@printer_set_up = Factory.build(:printer_set_up)

3.times {
pf = Factory.create(:printer_format)
@printer_set_up.printer_formats << page_assembly =" Factory.create(:page_assembly," printer_id =""> @printer_set_up.printer_id, :job_id => @job.id)
end


PrinterFormat and PrinterSetUp both have HABTM relationships with each other.

Friday, 31 July 2009

A little thing that saved me

Factory Girl stringify_keys error in Create Test.

Now have to work out why everything else is going wrong ... I think I have to work out how to stop other classes from screwing up the thing I am testing. Sounds like I need stubs and/or mocks. Just have to work out how to use them ...

Tuesday, 28 July 2009

Rich list of cucumber tutorials etc

http://wiki.github.com/aslakhellesoy/cucumber/tutorials-and-related-blog-posts

redgreen not working

Could not get this bugger to work at all.
After much fiddling around - and a lot of googling, the penultimate comment on here solved it.
There was a lot of talk on sites about edit the .autotest file - but, er, on my install I had three .autotest files - which one to edit?
As it turns out, none of them. I had to make my own in the ~/ directory.

I am using SSH to remote into a RHEL5 box.
did a
$> vim ~/.autotest

got the usual vim type new file thing
and then typed

require 'redgreen/autotest'

yes - that way round, and NOT require 'autotest/redgreen'.
Save that (remembering not to hit Apple-S which sends Vim into a right old state) and at long last glorious living technicolour. Well, red and green at least - oh and amber too.
Second step on the journey of a thousand miles.

Having spent some time trawling around and looking at testing, and following the advice of the ever sagacious Ryan Bates, I think it is worth investing the time and effort in getting a solid test environment built.
To that end it looks like the following
Mocha
RSpec
Cucumber
Webrat
FactoryGirl.
It worries me that that is five packages to try and get working. However, I have got the Unit tests working pretty well so far using fixtures etc.
I think I am going to try and use FactoryGirl rather than fixtures. My brief foray into fixtures was not a happy one. They seem very brittle.

Monday, 27 July 2009

Factory Girl

Wow - doesn't take long to get pissed off with fixtures, does it? They are incredibly brittle and I spent a load of time hacking fixtures to get them to pass the tests that I knew it would pass. Seemed like a pretty good waste of time.
Soooo - truffling around I found the excellent Ryan Bates had produced a very useful railscast on Factory Girl which seems - one functional test completed - to be a lot better.
I still want to get my head around cucumber and rspec - even shelling out a few bob to buy the book.
It seems very much the right way to go.

Friday, 24 July 2009

test, test, test

Ok. Have managed (eventually) to get all the Unit tests to pass. That was a very illustrative experience and highlighted some issues - such as not getting all the associations completely nailed.
Funny how a quick "test" in the browser isn't really up to the job at all.
There are some issues with testing callbacks - doesn't seem anyway to pass information to and from the callback.

Now trying to crack the controller tests. The scaffold tests have, so far, failed in rather too many ways.
1) Failure:
test_should_create_brisque_set_up(BrisqueSetUpsControllerTest) [test/functional/brisque_set_ups_controller_test.rb:16]:
"BrisqueSetUp.count" didn't change by 1.
<3> expected but was
<2>.

2) Failure:
test_should_update_brisque_set_up(BrisqueSetUpsControllerTest) [test/functional/brisque_set_ups_controller_test.rb:35]:
Expected response to be a <:redirect>, but was <200>


Not quite sure why this should happen since this is an untouched-by-human-hands object.
We'll find out ...