首页 > 解决方案 > 如何将枚举字符串值转换为列类型?

问题描述

我需要创建一个按列动态过滤模型的方法。它需要接收我想要过滤的列(称为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 查询中,它会爆炸,因为在数据库中它将整数列与字符串进行比较。

你知道我如何转换一个字符串值来匹配数据库中列的类型吗?

谢谢!

标签: ruby-on-railsactiverecord

解决方案


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

推荐阅读