I have a set of STI subclasses inheriting from a User
base class. I am finding that under certain conditions inside a subclass' definition, queries on the subclasses do not correctly use the type
condition.
class User < ActiveRecord::Base
# ...
end
class Admin < User
Rails.logger.info "#{name}: #{all.to_sql}"
# ...
end
When loading the Rails console in development, it does what I would expect:
Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin')
But when hitting the app (localhost / pow), it is missing the type
condition and I get this:
Admin: SELECT `users`.* FROM `users`
But not from the app when when deployed to a staging server:
Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin')
This, of course, causes any queries executed here in the dev app (but not from the console) to be incorrect. Specifically, I am trying to preload a (small) cache of existing db values in order to create a few helpful methods based on those data. Without the type scope, the cache is obviously incorrect!
From the same location (Admin
), we get the following confusing contradiction:
[11] pry(Admin)> Admin.finder_needs_type_condition?
=> true
[12] pry(Admin)> Admin.send(:type_condition).to_sql
=> "`users`.`type` IN ('Admin')"
[13] pry(Admin)> Admin.all.to_sql
=> "SELECT `users`.* FROM `users`"
Further, I defined a throwaway subclass Q < User
inside the user.rb
file. I logged Q.all.to_sql
from its definition, from the definition of Admin
, and from a view. In that order, we get:
From Q: Q: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Q')
From Admin: Q: SELECT `users`.* FROM `users`
From View: Q: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Q')
What could cause, in the first line of the Admin
subclass definition in admin.rb, any subclass of User
to fail to use its type_condition
?
This is causing development tests to fail, and so is of some consequence to my app. What on earth could be causing this difference in behavior? Can anyone think of a more general way around the problem of not having the STI conditions defined on a subclass during its definition only in the development app environment?
finder_needs_type_condition?
method is good to know about: yet, it returnstrue
when I pry from the app while still giving me"SELECT
users.* FROM
users"
as in the question. Relatedly, I found the private methodtype_condition
, which, when callingto_sql
on, yields"`users`.`type` IN ('Admin')"
. So something is clearly broke. – Help