我需要创建一种按列动态过滤模型的方法。它需要接收我要过滤的列(称为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
的问题。枚举是db上的整数,但是当我执行强制转换时,它将返回相同的字符串值,因为对于rails来说,它是一个字符串。然后,在where查询中,它爆炸,因为在数据库中它将整数列与字符串进行比较。
您知道我如何转换字符串值以匹配数据库中列的类型吗?
谢谢!
答案 0 :(得分:1)
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
方法。它将值从红宝石类型转换为数据库知道如何理解的类型。
Order.attribute_types["status"].serialize("cancelled") # => 2