我有一個存儲在MySQL表中BINARY(16)字段中的UUID的模型。我希望能夠透明地將十六進制uuid轉換爲setter方法的二進制文件,並在使用getter方法時將其轉換回來。如何透明地修改模型中的ActiveRecord方法?
什麼是「正確」的方式?
我有一個存儲在MySQL表中BINARY(16)字段中的UUID的模型。我希望能夠透明地將十六進制uuid轉換爲setter方法的二進制文件,並在使用getter方法時將其轉換回來。如何透明地修改模型中的ActiveRecord方法?
什麼是「正確」的方式?
您覆蓋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
當然,你想要的二進制列的,因爲你發送的原始字節到數據庫。像這樣的遷移:
class AddUuidToUsers
def self.up
execute "ALTER TABLE users ADD uuid BINARY(16)"
end
end
以每個模型或每個字段爲基礎重寫getter和setter並不像教ActiveRecord一般如何處理BINARY(16)那樣優雅。 – 2010-02-09 04:31:11
使用add_column with:binary不提供BINARY類型。它會給出一個BLOB類型。 – 2010-02-09 04:31:44
我也試過了上面的代碼示例,並遇到了一些問題。首先,我認爲你的意思是包裝(「C *」)而不是包裝(C *)。但更一般的說,如果可能的話,我會讓MySQL處理與BINARY(16)類型的轉換,而不是在Ruby中進行轉換。根據Aaron Scrugs在http://code.openark.org/blog/mysql/common-data-types-errors-compilation上的評論(#11),「HEX()和UNHEX()函數允許你在二進制數據和適用於應用程序的十六進制字符串。「 – 2010-02-09 04:41:34
我看了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
如果你得到這個工作,我希望你分享你的想法。像馬修一樣,我希望ActiveRecord有一個更清潔的API來添加列類型。
下面的答案和評論有幫助嗎?你找到了適合你的東西嗎? – 2010-02-24 15:50:40