Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
sample project in Rails 3.0.x to expose a STI bug
Ruby JavaScript
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
app
config
db
doc
lib/tasks
public
script
test
vendor/plugins
.gitignore
Gemfile
Gemfile.lock
README
Rakefile
config.ru

README

Here's how to expose the bug. I consider it a bug at least ;-)

rake db:setup

# I have some sample data in seeds.rb that should now be inserted.

rails c

ruby-1.9.2-p180 :001 > Production.first.contributers(true)
 => []

SQL output:

Production Load (0.3ms)  SELECT "productions".* FROM "productions" LIMIT 1
  Author Load (0.2ms)  SELECT "users".* FROM "users" INNER JOIN "production_contributions" ON "users".id = "production_contributions".user_id WHERE "users"."type" = 'Author' AND (("production_contributions".production_id = 1))


It's not finding any records, but the production does have a contributer, only this contributer is an Admin and inherits from Author, using STI. 

now change the config so it says:

config.cache_classes = false

ruby-1.9.2-p180 :002 > Production.first.contributers(true)
 => [#<Admin id: 3, email: "admin@example.com", type: "Admin">] 

SQL output:
Production Load (0.4ms)  SELECT "productions".* FROM "productions" LIMIT 1
  Author Load (0.4ms)  SELECT "users".* FROM "users" INNER JOIN "production_contributions" ON "users".id = "production_contributions".user_id WHERE (("users"."type" = 'Author' OR "users"."type" = 'Admin')) AND (("users"."type" = 'Author' OR "users"."type" = 'Admin')) AND (("production_contributions".production_id = 1))

With cache_classes = true everything works as expected. Rails knows to also select other user types. I don't quite understand the duplicate where clause, but it doesn't seem to blow anything up.

a Quick Fix 
===========

I tried requiring the "author" and "admin" in user.rb but that gave my some weird errors, especially with devise. 

What seems to work fine is to just mention the models in an after_initialize so autoloading kicks in. Only needed in envs where cache_classes = false.

config.after_initialize do
  User;Author;Admin 
end
Something went wrong with that request. Please try again.