← Back to Upcase

ActiveRecord::RecordNotFound: querying STI models


(Alex Bush) #1

I have 3 STI models:

class Party < ActiveRecord::Base end
class Festival < Party end
class MultiEventFestival < Festival end

I have created MultiEventFestival and activerecord assigned it auto-incremented db id of 52.

When I fetch it via MultiEventFestival.find 52 in console I get the correct result:

>> MultiEventFestival.find 52
MultiEventFestival Load (0.6ms)  SELECT `parties`.* FROM `parties` WHERE `parties`.`type` IN ('MultiEventFestival') AND `parties`.`id` = 52 LIMIT 1
=> #<MultiEventFestival id: 52, type: "MultiEventFestival", name: "Multi Event 1", description: "Some Desc Here", location: nil, map: nil, start_date: "2014-02-08 01:43:52", website: nil, facebook_page: nil, twitter_page: nil, tickets_page: nil, city: "San Francisco", created_at: "2014-02-08 01:43:52", updated_at: "2014-02-08 03:42:26", logo: nil, small_logo: nil, country: "USA", latitude: nil, longitude: nil, end_date: "2014-02-08 01:43:52", popular: false, position: 2, venue_id: nil>

And then when I fetch it via super class I get the right result as well:

>> Festival.find 52
  Festival Load (0.8ms)  SELECT `parties`.* FROM `parties` WHERE `parties`.`type` IN ('Festival', 'MultiEventFestival') AND `parties`.`id` = 52 LIMIT 1
=> #<MultiEventFestival id: 52, type: "MultiEventFestival", name: "Multi Event 1", description: "Some Desc Here", location: nil, map: nil, start_date: "2014-02-08 01:43:52", website: nil, facebook_page: nil, twitter_page: nil, tickets_page: nil, city: "San Francisco", created_at: "2014-02-08 01:43:52", updated_at: "2014-02-08 03:42:26", logo: nil, small_logo: nil, country: "USA", latitude: nil, longitude: nil, end_date: "2014-02-08 01:43:52", popular: false, position: 2, venue_id: nil>

But here is the interesting bug I found. When I quit console and reopen it again and call Festival.find 52 before I call MultiEventFestival.find 52 I get ActiveRecord::RecordNotFound: error:

>> Festival.find 52
  Festival Load (0.4ms)  SELECT `parties`.* FROM `parties` WHERE `parties`.`type` IN ('Festival') AND `parties`.`id` = 52 LIMIT 1
ActiveRecord::RecordNotFound: Couldn't find Festival with id=52 [WHERE `parties`.`type` IN ('Festival')]
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/activerecord-3.2.12/lib/active_record/relation/finder_methods.rb:341:in `find_one'
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/activerecord-3.2.12/lib/active_record/relation/finder_methods.rb:312:in `find_with_ids'
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/activerecord-3.2.12/lib/active_record/relation/finder_methods.rb:107:in `find'
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/activerecord-3.2.12/lib/active_record/querying.rb:5:in `find'
	from (irb):2
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/railties-3.2.12/lib/rails/commands/console.rb:47:in `start'
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/railties-3.2.12/lib/rails/commands/console.rb:8:in `start'
	from /Users/Alex/.rvm/gems/ruby-1.9.3-p392@festival/gems/railties-3.2.12/lib/rails/commands.rb:41:in `<top (required)>'
	from script/rails:6:in `require'
	from script/rails:6:in `<main>'

Am I missing something or doing something wrong?


(Derek Prior) #2

What version of Rails are you running? Can you post the models? Do you have any default scopes on them that might be doing something odd? When I run queries on the base class in an STI setup (Rails 4.0.x), I don’t see any types in the resultant where clause.


(Alex Bush) #3

@derekprior I figured it out.

Here is my detailed writeup with the problem outline and a simple solution. Hope will save someone a google search :smile:

The error was showing up only in development mode and it turned out that it was happening due to lazy loading of classes in Rails 3(3.1.2) in development mode.

Festival.find 52
Festival Load (0.4ms) SELECT parties.* FROM parties WHERE parties.type IN (‘Festival’) AND parties.id = 52 LIMIT 1
ActiveRecord::RecordNotFound: Couldn’t find Festival with id=52 [WHERE parties.type IN (‘Festival’)]

was suppose to search for Festival number 52 in 'Festival' and 'MultiEventFestival' since the models subclass each other:

class Party < ActiveRecord::Base 
end
class Festival < Party 
end
class MultiEventFestival < Festival 
end