ruby-on-rails - 如何将枚举字符串值转换为列类型?
问题描述
我需要创建一个按列动态过滤模型的方法。它需要接收我想要过滤的列(称为attr_name
),operator
作为字符串,以及value
作为字符串。
我需要先将字符串值转换为数据库列类型,然后才能进行 sql 查询。
scope :filtered_by_attribute, (lambda do |attr_name, operator, value|
comparing_value = Customer.attribute_types[attr_name].cast(value)
casting_error = !value.nil? && comparing_value.nil?
raise I18n.t('api.errors.unaplicable_customer_scope') if casting_error
sql_query = sanitize_sql("#{attr_name} #{operator} ?")
where(sql_query, comparing_value)
end)
上面的问题是当涉及到enums
. 枚举是数据库上的整数,但是当我执行转换时,它将返回相同的字符串值,因为对于 rails 它是一个字符串。然后,在 where 查询中,它会爆炸,因为在数据库中它将整数列与字符串进行比较。
你知道我如何转换一个字符串值来匹配数据库中列的类型吗?
谢谢!
解决方案
该cast
方法在将用户输入的值分配给实例时将其强制转换。在您分配字符串值的情况下,enum
它仍然是字符串值。只有在数据库中持久化时才会将其转换为整数。
class Order < ActiveRecord::Base
enum status: {confirmed: 1, cancelled: 2}
end
# this is where the `cast` method is called
@order.status = "cancelled"
# still a string since the `cast` method didn't do anything.
@order.status # => "cancelled"
你真正需要的是serialize
方法。它将一个 ruby 类型的值转换为数据库知道如何理解的类型。
Order.attribute_types["status"].serialize("cancelled") # => 2
推荐阅读
- oauth - eBay OAuth 无法获取令牌
- mysql - MySql 服务器不是从命令提示符启动的
- google-cloud-platform - 所需的复合索引不存在,但在 index.yaml 中定义
- java - Kafka Consumer 输出过多的 DEBUG 语句
- azure - 如何在 Azure cosmos DB 中使用双引号保存数据
- c++ - 使用 sftp_open() 在 C++ 中使用 SFTP libssh 将文件从本地复制到远程时,文件返回 NULL 值
- bootloader - 如何从保护模式(或 C 代码)调用 PXE API?
- java - AnimationDrawable 在片段中不起作用。
- ios - GoogleService-Info.plist 文件中的 iOS Firebase IS_ADS_ENABLED 标志
- java - 错误的中位数答案