ActiveRecord:查询未为STI子类使用正确的类型条件 [英] ActiveRecord: query not using correct type condition for STI subclass

查看:62
本文介绍了ActiveRecord:查询未为STI子类使用正确的类型条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一组从 User 基类继承的STI子类.我发现在子类的定义内的某些条件下,对子类的查询不能正确使用 type 条件.

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

在开发中加载Rails控制台时,它会达到我的期望:

When loading the Rails console in development, it does what I would expect:

Admin: SELECT `users`.* FROM `users` WHERE `users`.`type` IN ('Admin')

但是当点击应用程序(localhost/pow)时,它缺少 type 条件,我得到了:

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')

这当然会导致在dev应用程序中(但不是从控制台)在此处执行的所有查询均不正确.具体来说,我正在尝试预加载现有db值的(小型)缓存,以便基于这些数据创建一些有用的方法.没有类型作用域,缓存显然是不正确的!

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!

从同一位置( Admin ),我们得到以下令人困惑的矛盾:

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`"

此外,我定义了一个废弃子类 Q< user.rb 文件中的User .我从Q.all.to_sql 的定义, Admin 的定义以及视图中登录.按此顺序,我们得到:

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')

在admin.rb中 Admin 子类定义的第一行中, User 的任何子类可能无法使用其的原因是什么?是type_condition ?

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?

这导致开发测试失败,因此对我的应用程序也有一定影响.到底是什么原因导致了这种行为上的差异?谁能想到一个更一般的方法来解决在子类定义期间仅在开发应用程序环境中没有在子类上定义STI条件的问题?

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?

推荐答案

生产与开发之间的一个区别是应用程序配置中的以下行:

One difference between production and development is the following line inside of the application configuration:

# config/environments/development.rb
config.eager_load = false

vs.

# config/environments/production.rb
config.eager_load = true

因此,在您的生产环境中,启动应用程序时会加载所有clase.当 eager_load 设置为false时,Rails将在您首次加载 Admin 类时尝试自动加载 User 类.

So on your production environment, all your clases are loaded when the app is started. When eager_load is set to false, Rails will try to autoload your User class when you first load the Admin class.

鉴于此,我假设您还有另一个名为 User 的类或模块.

Given that, I'd assume that you have another class or module named User.

仅供参考:ActiveRecord有一个名为 finder_needs_type_condition?的方法.对于使用STI的类,它应该返回true:

FYI: ActiveRecord has a method called finder_needs_type_condition?. It should return true for a class that uses STI:

User.finder_needs_type_condition? # should be false
Admin.finder_needs_type_condition? # should be true

这篇关于ActiveRecord:查询未为STI子类使用正确的类型条件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆