我使用以下code snippet from the Rails docs将IP转换为整数,然后再将它们插入数据库:
composed_of :user_ip,
:class_name => 'IPAddr',
:mapping => %w(user_ip to_i),
:constructor => Proc.new { |ip| IPAddr.new(ip, Socket::AF_INET) },
:converter => Proc.new { |ip| ip.is_a?(Integer) ? IPAddr.new(ip, Socket::AF_INET) : IPAddr.new(ip.to_s) }
然后,通过这个简单的验证,使用composed_of块:
validates_uniqueness_of :user_ip
但是在尝试创建新对象时,验证反过来会引发错误:
TypeError: Cannot visit IPAddr
删除验证,错误消失。
如果我理解正确,就会发生这种情况,因为:user_ip成为IPAddr对象,而且不适合ActiveRecord。这是正确的,如果是这样,有没有办法绕过它?
答案 0 :(得分:2)
不确定您是否找到了解决方案,但我可以通过向Arel添加访问方法在我的gem中修补它。
您应该可以执行以下操作以使其正常工作。这基于Arel converts values对于其他类型对象(如日期)的方式。不确定是否需要将值转换为字符串,但它可能只是一个整数。
module Arel
module Visitors
class ToSql
def visit_IPAddr
quote(value.to_i)
end
end
end
end
我需要能够动态生成这些方法,所以我在我的gem中使用了以下内容:
Arel::Visitors::ToSql.class_eval do
define_method "visit_#{klass.name}", lambda {|value| quote(value.to_s) }
end