sfsn
sfsn

Reputation: 295

ActiveRecord::Base#find returns no records in Single Table Inheritance (STI)

app/models

class Amodel < ActiveRecord::Base
end

class Bmodel < Amodel
end

class Cmodel < Bmodel  
end

db/migrate

create_table :amodels do |t|
  t.string :type
end

on script/console...

$ script/console
Loading development environment (Rails 2.3.4)
>> Cmodel.create
=> #<Cmodel id: 1, type: "Cmodel">
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

ok, but Bmodel returns no records after rebooting console like:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Bmodel.find(:all)
=> []

however, it works after accessing Cmodel:

>> Cmodel
=> Cmodel(id: integer, type: string)
>> Bmodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

Amodel works like:

>> exit
$ script/console
Loading development environment (Rails 2.3.4)
>> Amodel.find(:all)
=> [#<Cmodel id: 1, type: "Cmodel">]

Does anyone know why it works like this?

Rails: 2.3.4
Ruby: 1.8.7
OS: Ubuntu 9.0.4

Upvotes: 1

Views: 406

Answers (1)

Fran&#231;ois Beausoleil
Fran&#231;ois Beausoleil

Reputation: 16535

Because of the way ActiveRecord STI is built. When a class is loaded, it registers with it's parent (see the #inherited hook). Thus, when you call Amodel#find or Bmodel#find, if the subclass isn't known, it can't be found yet.

In production, this problem wouldn't be apparent, because Rails will load all models when it starts, preventing this kind of problem.

Upvotes: 2

Related Questions