ruby-on-rails - 在构造 SQL 查询时,ActiveRecord 是否处理按值查找 `enum` ?

标签 ruby-on-rails postgresql ruby-on-rails-4 activerecord enums

我有一个ActiveRecord enum在我的模型上定义如下:

class ApiKey < ApplicationRecord
  enum api_version: { v1: -1, v2: 0, v3: 1 }
end

当我尝试通过枚举名称进行查询时,我注意到 ActiveRecord 未正确构建查询。 例如

> ApiKey.where(owner_type: 'User', api_version: 'v3').to_sql
=> "SELECT \"api_keys\".* FROM \"api_keys\" WHERE \"api_keys\".\"owner_type\" = 'User' AND \"api_keys\".\"api_version\" = 0"

我指定了 v3,因此我希望生成的查询能够正确地将其原始枚举值查找为 1,但它使用的是 0 .

当然,我可以自己进行枚举映射并让它产生正确的结果:

> ApiKey.where(owner_type: 'User', api_version: ApiKey.api_versions['v3']).to_sql
=> "SELECT \"api_keys\".* FROM \"api_keys\" WHERE \"api_keys\".\"owner_type\" = 'User' AND \"api_keys\".\"api_version\" = 1"

这是 ActiveRecord 中的错误还是它不支持这种方式的枚举查找?我想它会的,因为枚举的全部目的是能够使用友好/人类可读的名称。

谢谢!

注释

  • ApiKey#api_version 列的类型为整数
  • 我使用的是 Postgres 9.5
  • 我正在使用activerecord-4.2.11.1

追踪行为

以下是 ActiveRecord 源中发生的情况:

最佳答案

框架在 https://github.com/rails/rails/blob/master/activerecord/lib/active_record/type_caster/connection.rb#L14 中查找列类型然后通过EnumType调用序列化:https://github.com/rails/rails/blob/master/activerecord/lib/active_record/enum.rb#L142

如果您将代码从字符串更改为符号(就像枚举定义中所写的那样),它应该可以工作。

另一方面,最好不要使用数字枚举值,因为它们维护起来有问题:数据只能通过插入记录的应用程序的特定版本来读取。 由于您已经在使用 Postgres,请考虑使用正确的枚举类型。有一些很好的库,例如 pg_enumtorque支持这一努力。

关于ruby-on-rails - 在构造 SQL 查询时,ActiveRecord 是否处理按值查找 `enum` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59035778/

相关文章:

ruby-on-rails - 在 Rails 4 中为脚手架 Controller 自动生成路由?

ruby-on-rails - Assets 过滤器错误: ckeditor in rails 4. 1.0

ruby-on-rails - 在 Rails 中自定义 Devise View

ruby-on-rails - 嵌套 has_many 关系的范围

javascript - 使用 accepts_nested_attributes_for 的 rails 中的三级嵌套表单

postgresql - Postgres 更新语句

mysql - 来自多个模型的包含、选择、排序、限制(单个查询)

ruby-on-rails - 为什么乘客如此积极地点击我的索引页面

sql 最大(val1,val2)?

postgresql - 使用带有 liquibase 变更集上下文属性的 spring boot 配置文件来管理变更集范围