Skip to content

Instantly share code, notes, and snippets.

@fxn
Created January 11, 2010 13:05
Show Gist options
  • Save fxn/274219 to your computer and use it in GitHub Desktop.
Save fxn/274219 to your computer and use it in GitHub Desktop.
seach for STI grandchildren who are leaves
# Computes STI models who are grandchildren or more.
#
# In a STI the root class and its subclasses work normally, but if there are
# grandchildren we need to preload them. Reason is, given A < B < C, if you
# for example compute B.count without loading A, only B records are taken into
# account in the query (where a clause about the type column intervenes). This
# is not a bug, Active Record is simply not aware of A. Once it is, the clause
# becomes an OR with all relevant types.
#
# I used this script to compute them.
ActiveRecord::Base.instance_eval do
def concrete_superclass
begin
s = superclass
end while s.abstract_class?
s
end
def is_sti?
concrete_superclass != ActiveRecord::Base
end
def is_sti_grandchild_or_more?
is_sti? && concrete_superclass.is_sti?
end
def needs_preloading?
is_sti_grandchild_or_more? && subclasses_of(self).empty?
end
end
Dir["#{Rails.root}/app/models/**/*.rb"].each do |model|
require_or_load model
end
puts subclasses_of(ActiveRecord::Base).
select(&:needs_preloading?).
map(&:name).
sort
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment