我有一组从用户基类继承的STI子类.我发现在某个子类的定义条件下,对子类的查询不能正确地使用类型条件.
class User < ActiveRecord::Base # ... end class Admin < User Rails.logger.info "#{name}: #{all.to_sql}" # ... end
在开发中加载Rails控制台时,会按照我的期望:
Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin')
但是当点击应用程序(localhost / pow)时,它缺少类型条件,我得到:
Admin: SELECT `users`.* FROM `users`
但是当部署到分段服务器时不能从应用程序发出:
Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin')
这当然导致在dev应用程序(但不是从控制台)执行的任何查询都是错误的.具体来说,我正在尝试预加载现有数据库值的(小)缓存,以便根据这些数据创建一些有用的方法.没有类型范围,缓存显然是不正确的!
从同一位置(管理员),我们得到以下令人困惑的矛盾:
[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`"
此外,我定义了一个一次性的子类Q user.rb文件中的用户.我从其定义,从管理员的定义和视图记录了Q.all.to_sql.按照这个顺序,我们得到:
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')
在admin.rb的Admin子类定义的第一行中可能会导致User的任何子类无法使用其type_condition?
这是导致开发测试失败,对我的应用程序也有一些后果.地球上可能会导致行为差异?任何人都可以想到一个更通用的方法来解决在定义只有在开发应用程序环境中没有在子类上定义STI条件的问题?
解决方法
生产和开发之间的一个区别是应用程序配置中的以下行:
# config/environments/development.rb config.eager_load = false
与
# config/environments/production.rb config.eager_load = true
所以在您的生产环境中,应用程序启动时,所有的夹子都会被加载.
当eager_load设置为false时,当您首次加载Admin类时,Rails将尝试自动加载User类.
假设我假设你有另一个类或名为User的模块.
FYI:ActiveRecord有一个名为finder_needs_type_condition?的方法.对于使用STI的课程应该返回true:
User.finder_needs_type_condition? # should be false Admin.finder_needs_type_condition? # should be true