ActiveRecord - nil object when you didn't expect it

Hi,

I have the following code in a RoR project, models and tests are all in the proper directories:

require File.dirname(__FILE__) + '/../test_helper'

class GalleryTest < Test::Unit::TestCase   fixtures :galleries

  @gallery = nil

  def test_presence_of     @gallery = Gallery.new     @gallery.title = 'My test gallery'     @gallery.nr = 123     image = Image.new(1, 100, 'jpg')     @gallery.images = Array.new     @gallery.images << image     @gallery.save

    assert @gallery.valid?   end end

class Gallery < ActiveRecord::Base   validates_presence_of :title, :nr, :images   validates_numericality_of :nr   validates_length_of :title, :in => 1..255

  has_many :images end

class Image < ActiveRecord::Base   validates_presence_of :nr, :sort_nr, :ext   validates_presence_of :sort_nr   validates_presence_of :ext

  belongs_to :gallery

  def initialize(nr, sort_nr, ext)     @nr = nr     @sort_nr = sort_nr     @ext = ext   end end

When I run the gallery test file, ruby shows me the following error:

test_presence_of(GalleryTest): NoMethodError: You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.     c:/program files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.6/lib/active_ record/base.rb:1871:in `read_attribute' ... record/transactions.rb:121:in `transaction'     c:/program files/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.6/lib/active_ record/transactions.rb:129:in `save'     test/unit/gallery_test.rb:23:in `test_presence_of'

It has something to do with gallery.images, but I can't figure out how to fix this.

Another question (offtopic): Why does it take 10 seconds for the test to start running? This gets annoying when you want to "code a little, test a little".

Hi, class Image < ActiveRecord::Base validates_presence_of :nr, :sort_nr, :ext validates_presence_of :sort_nr validates_presence_of :ext

belongs_to :gallery

def initialize(nr, sort_nr, ext)    @nr = nr    @sort_nr = sort_nr    @ext = ext end end

You're overriding activerecord's initialize function, but without calling super, so stuff is not initialized properly (and thus crazy stuff happens. In addition activerecord attributes are not persisted as instance variables so you inititialize function doesn't do what you think it does. Why do you need a custom initialize at all ?

Another question (offtopic): Why does it take 10 seconds for the test to start running? This gets annoying when you want to "code a little, test a little".

Probably because certain bits of ruby are a lot slower on windows (there was another thread about this a day or 2 ago)

Fred

Frederick Cheung wrote:

   @nr = nr    @sort_nr = sort_nr    @ext = ext end end

You're overriding activerecord's initialize function, but without calling super, so stuff is not initialized properly (and thus crazy stuff happens. In addition activerecord attributes are not persisted as instance variables so you inititialize function doesn't do what you think it does. Why do you need a custom initialize at all ?

Another question (offtopic): Why does it take 10 seconds for the
test to start running? This gets annoying when you want to "code a little,
test a little".

Probably because certain bits of ruby are a lot slower on windows (there was another thread about this a day or 2 ago)

Fred

Can't test it right now, but super could be the issue indeed. I did a initialize override so I could do this

my_image = Image.New(123, 1, 'jpg')

instead of

my_image = Image.New my_image.nr = 123 my_image.sort_nr = 1 my_image.ext = 'jpg'

Is there another way to send arguments to initialize without doing an override?

Image.new :nr => 123, :sort_nr => 1, :ext => 'jpg'

Fred

Frederick Cheung wrote: