我有一个模型,UUID存储在MySQL表的BINARY(16)字段中。我希望能够透明地将十六进制uuid转换为二进制用于setter方法,并在我使用getter方法时返回。
什么是'正确'的方式?
答案 0 :(得分:7)
你覆盖了setter和getter:
class User < ActiveRecord::Base
def uuid=(value)
@uuid = write_attribute(:uuid, value.scan(/../).map {|n| n.to_i(16)}.pack("C*"))
end
def uuid
@uuid ||= read_attribute(:uuid).unpack("C*").map {|n| sprintf("%02x", n)}.join
end
end
当然,您需要一个BINARY列,因为您正在向DB发送原始字节。像这样的迁移:
class AddUuidToUsers
def self.up
execute "ALTER TABLE users ADD uuid BINARY(16)"
end
end
答案 1 :(得分:1)
我查看了ActiveRecord 2.3.5(mysql_adapter.rb)的源代码。查看NATIVE_DATABASE_TYPES哈希表明它不支持BINARY(16)数据类型:
NATIVE_DATABASE_TYPES = {
:primary_key => "int(11) DEFAULT NULL auto_increment PRIMARY KEY".freeze,
:string => { :name => "varchar", :limit => 255 },
:text => { :name => "text" },
:integer => { :name => "int", :limit => 4 },
:float => { :name => "float" },
:decimal => { :name => "decimal" },
:datetime => { :name => "datetime" },
:timestamp => { :name => "datetime" },
:time => { :name => "time" },
:date => { :name => "date" },
:binary => { :name => "blob" },
:boolean => { :name => "tinyint", :limit => 1 }
}
另请注意:二进制文件不是您想要的,因为它会创建一个BLOB列。
如果您有兴趣,我建议扩展ActiveRecord以支持BINARY(16)类型。
更新:经过一些搜索后,Matthew Higgins的以下博客文章似乎很有希望(“虽然可以在迁移中执行任意SQL语句,但另一种方法是扩展MySql适配器以支持新类型的列。”): http://www.strictlyuntyped.com/2008/07/mysql-lovin-part-2-adding-new-column.html
如果你让它发挥作用,我希望你能分享你的想法。像Matthew一样,我希望看到ActiveRecord有一个更清晰的API来添加列类型。